实验定义
The @experimental
注释允许定义一个 API,该 API 不保证向后二进制或源代码兼容性。此注释可以放置在术语或类型定义上。
对实验性定义的引用
实验性定义只能在实验性范围内引用。实验性范围定义如下
-
实验性
def
、val
、var
、given
或type
的 RHS 是一个实验性范围。示例Example 1
import scala.annotation.experimental @experimental def x = () def d1 = x // error: value x is marked @experimental and therefore ... @experimental def d2 = x val v1 = x // error: value x is marked @experimental and therefore ... @experimental val v2 = x var vr1 = x // error: value x is marked @experimental and therefore ... @experimental var vr2 = x lazy val lv1 = x // error: value x is marked @experimental and therefore ... @experimental lazy val lv2 = x
Example 2
import scala.annotation.experimental @experimental val x = () @experimental def f() = () @experimental object X: def fx() = 1 def test1: Unit = f() // error: def f is marked @experimental and therefore ... x // error: value x is marked @experimental and therefore ... X.fx() // error: object X is marked @experimental and therefore ... import X.fx fx() // error: object X is marked @experimental and therefore ... @experimental def test2: Unit = // references to f, x and X are ok because `test2` is experimental f() x X.fx() import X.fx fx()
Example 3
import scala.annotation.experimental @experimental type E type A = E // error type E is marked @experimental and therefore ... @experimental type B = E
Example 4
import scala.annotation.experimental @experimental class A @experimental type X @experimental type Y = Int @experimental opaque type Z = Int def test: Unit = new A // error: class A is marked @experimental and therefore ... val i0: A = ??? // error: class A is marked @experimental and therefore ... val i1: X = ??? // error: type X is marked @experimental and therefore ... val i2: Y = ??? // error: type Y is marked @experimental and therefore ... val i2: Z = ??? // error: type Y is marked @experimental and therefore ... ()
Example 5
@experimental trait ExpSAM { def foo(x: Int): Int } def bar(f: ExpSAM): Unit = {} // error: error form rule 2 def test: Unit = bar(x => x) // error: reference to experimental SAM ()
-
实验性
def
、val
、var
、given
和type
的签名,或class
和trait
的构造函数是实验性范围。示例示例 1
import scala.annotation.experimental @experimental def x = 2 @experimental class A @experimental type X @experimental type Y = Int @experimental opaque type Z = Int def test1( p1: A, // error: class A is marked @experimental and therefore ... p2: List[A], // error: class A is marked @experimental and therefore ... p3: X, // error: type X is marked @experimental and therefore ... p4: Y, // error: type Y is marked @experimental and therefore ... p5: Z, // error: type Z is marked @experimental and therefore ... p6: Any = x // error: def x is marked @experimental and therefore ... ): A = ??? // error: class A is marked @experimental and therefore ... @experimental def test2( p1: A, p2: List[A], p3: X, p4: Y, p5: Z, p6: Any = x ): A = ??? class Test1( p1: A, // error p2: List[A], // error p3: X, // error p4: Y, // error p5: Z, // error p6: Any = x // error ) {} @experimental class Test2( p1: A, p2: List[A], p3: X, p4: Y, p5: Z, p6: Any = x ) {} trait Test1( p1: A, // error p2: List[A], // error p3: X, // error p4: Y, // error p5: Z, // error p6: Any = x // error ) {} @experimental trait Test2( p1: A, p2: List[A], p3: X, p4: Y, p5: Z, p6: Any = x ) {}
-
实验性
class
、trait
或object
的extends
子句是一个实验性范围。示例示例 1
import scala.annotation.experimental @experimental def x = 2 @experimental class A1(x: Any) class A2(x: Any) @experimental class B1 extends A1(1) class B2 extends A1(1) // error: class A1 is marked @experimental and therefore marked @experimental and therefore ... @experimental class C1 extends A2(x) class C2 extends A2(x) // error def x is marked @experimental and therefore
-
实验性
class
、trait
或object
的主体是一个实验性范围。示例示例 1
import scala.annotation.experimental @experimental def x = 2 @experimental class A { def f = x // ok because A is experimental } @experimental class B { def f = x // ok because A is experimental } @experimental object C { def f = x // ok because A is experimental } @experimental class D { def f = { object B { x // ok because A is experimental } } }
-
实验性定义的注释位于实验性范围内。示例
示例 1
import scala.annotation.experimental @experimental class myExperimentalAnnot extends scala.annotation.Annotation @myExperimentalAnnot // error def test: Unit = () @experimental @myExperimentalAnnot def test: Unit = ()
-
使用 Nightly 或 Snapshot 版本的编译器编译的任何代码都被视为处于实验性范围内。可以使用
-Yno-experimental
编译器标志禁用它并作为正式版本运行。
在任何其他情况下,对实验性定义的引用都会导致编译错误。
实验性覆盖
对于覆盖成员 M
和被覆盖成员 O
,如果 O
不是实验性的,那么 M
必须是非实验性的。
这确保了我们不会出现意外的二进制不兼容性,例如以下更改。
class A:
def f: Any = 1
class B extends A:
- @experimental def f: Int = 2
测试框架
测试可以定义为实验性的。测试框架可以使用反射执行测试,即使它们在实验性类、对象或方法中。示例
示例 1
接触实验性 API 的测试可以按如下方式编写
import scala.annotation.experimental
@experimental def x = 2
class MyTests {
/*@Test*/ def test1 = x // error
@experimental /*@Test*/ def test2 = x
}
@experimental
class MyExperimentalTests {
/*@Test*/ def test1 = x
/*@Test*/ def test2 = x
}
-experimental
编译器标志
此标志允许在项目中使用任何实验性语言特性。它通过向所有顶级定义添加 @experimental
注解来实现这一点。因此,依赖项目也必须是实验性的。
本文内容