實驗性定義
@experimental
註解允許定義未保證向後二進制或來源相容性的 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
註解新增到所有頂層定義來執行此操作。因此,依賴專案也必須是實驗性的。
在本文中