Scala 3消除staging.Compiler重复设置-experimental标志提示的方法
问题描述
运行以下Scala 3测试代码时,频繁出现“Flag -experimental set repeatedly”提示(功能本身正常)。由于@experimental注解需要启用-experimental标志,移除(using settings)会导致测试失败,请问如何消除该提示?
import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers.shouldBe import scala.quoted.{Expr, staging} import scala.annotation.experimental final class MyTest extends AnyFlatSpec: import MyTest.fun private val settings = staging.Compiler.Settings.make(compilerArgs="-experimental"::Nil) private given staging.Compiler = staging.Compiler.make(getClass.getClassLoader)(using settings) "subject" should "behave as expected" in: def test(value: Int): Unit = staging.run('{fun(${Expr(value)})}) shouldBe value + 1 test(1) test(2) private object MyTest: @experimental def fun(x: Int): Int = x + 1
解决方案
出现该提示的核心原因是staging.Compiler实例被重复创建,导致-experimental参数被多次添加。以下是几种可行的解决方式:
方式一:复用单一Compiler实例
将Compiler实例的创建移到测试类的伴生对象中,确保整个测试流程只初始化一次Compiler,避免重复设置参数:
import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers.shouldBe import scala.quoted.{Expr, staging} import scala.annotation.experimental final class MyTest extends AnyFlatSpec: import MyTest.{fun, compiler} given staging.Compiler = compiler "subject" should "behave as expected" in: def test(value: Int): Unit = staging.run('{fun(${Expr(value)})}) shouldBe value + 1 test(1) test(2) private object MyTest: @experimental def fun(x: Int): Int = x + 1 // 仅初始化一次Compiler实例 private val settings = staging.Compiler.Settings.make(compilerArgs = "-experimental" :: Nil) val compiler: staging.Compiler = staging.Compiler.make(getClass.getClassLoader)(using settings)
方式二:全局启用experimental标志
通过JVM系统属性全局开启-experimental,无需在代码中手动传递参数给staging Compiler:
方式1:运行测试时添加JVM参数
sbt -Dscala.experimental=true test
方式2:在build.sbt中配置
Test / javaOptions += "-Dscala.experimental=true"
修改后代码可简化为:
private given staging.Compiler = staging.Compiler.make(getClass.getClassLoader)
方式三:禁用测试并行执行
若使用ScalaTest的并行测试特性,多个测试类实例会各自创建Compiler,导致重复提示。可通过以下方式禁用并行:
方式1:给测试类添加注解
import org.scalatest.DoNotDiscover import org.scalatest.flatspec.AnyFlatSpec @DoNotDiscover final class MyTest extends AnyFlatSpec: // 原有代码...
方式2:在build.sbt中全局配置
Test / parallelExecution := false
内容的提问来源于stack exchange,提问作者Koosha
相关产品推荐
相关产品推荐

