準引號

類型詳細資料

語言
此文件頁面特定於 Scala 2 中提供的功能,這些功能已在 Scala 3 中移除或由其他功能取代。除非另有說明,此頁面中的所有程式碼範例都假設您使用的是 Scala 2。

Denys Shabalin 實驗性質

空類型

空類型 (tq"") 是表示給定位置的類型未由使用者提供,且應由編譯器推論的正規方式

  1. 方法,回傳類型不明
  2. Val 或 Var,類型不明
  3. 匿名函式,具有未知的引數類型

類型識別碼

類似於 術語識別碼,可以根據名稱建構類型識別碼

scala> val name = TypeName("Foo")
name: universe.TypeName = Foo

scala> val foo = tq"$name"
foo: universe.Ident = Foo

並透過 解除提升將其解構回來

scala> val tq"${name: TypeName}" = tq"Foo"
name: universe.TypeName = Foo

建議在使用類型識別碼時,始終將名稱指定為 TypeName。未指定的模式等同於模式變數繫結。

單例類型

單例類型是一種表達正在引用的術語定義類型的途徑

scala> val singleton = tq"foo.bar.type".sr
singleton: String = SingletonTypeTree(Select(Ident(TermName("foo")), TermName("bar")))

scala> val tq"$ref.type" = tq"foo.bar.type"
ref: universe.Tree = foo.bar

類型投影

類型投影是選擇類型作為其他類型成員的基本途徑

scala> val proj = tq"Foo#Bar"
proj: universe.SelectFromTypeTree = Foo#Bar

scala> val tq"$foo#$bar" = proj
foo: universe.Tree = Foo
bar: universe.TypeName = Bar

類似於識別碼,建議始終將名稱指定為 TypeName。未指定的比對行為未來可能會變更。

作為一種便利,也可以選擇術語的類型成員

scala> val int = tq"scala.Int"
int: universe.Select = scala.Int

scala> val tq"scala.$name" = int
name: universe.TypeName = Int

但在語意上,此類選擇僅是單例類型和類型投影組合的捷徑

scala> val projected = tq"scala.type#Int"
projected: universe.SelectFromTypeTree = scala.type#Int

最後,類似於表達式,可以使用 superthis 選擇成員

scala> val superbar = tq"super.Bar"
superbar: universe.Select = super.Bar

scala> val tq"$pre.super[$parent].$field" = superbar
pre: universe.TypeName =
parent: universe.TypeName =
field: universe.Name = Bar

scala> val thisfoo = tq"this.Foo"
thisfoo: universe.Select = this.Foo

scala> val tq"this.${tpname: TypeName}" = thisfoo
tpname: universe.TypeName = Foo

已套用類型

參數化類型的實例化可以使用已套用類型(類型層級等同於類型應用)來表達

scala> val applied = tq"Foo[A, B]"
applied: universe.Tree = Foo[A, B]

scala> val tq"Foo[..$targs]" = applied
targs: List[universe.Tree] = List(A, B)

未套用類型的解構將導致 targs 被萃取為空清單

scala> val tq"Foo[..$targs]" = tq"Foo"
targs: List[universe.Tree] = List()

註解類型

類似於表達式,類型可以被註解

scala> val annotated = tq"T @Fooable"
annotated: universe.Annotated = T @Fooable

scala> val tq"$tpt @$annot" = annotated
tpt: universe.Tree = T
annot: universe.Tree = Fooable

複合類型

複合類型讓使用者可以表達多個類型的組合,並附有可選的精緻成員清單

scala> val compound = tq"A with B with C"
compound: universe.CompoundTypeTree = A with B with C

scala> val tq"..$parents { ..$defns }" = compound
parents: List[universe.Tree] = List(A, B, C)
defns: List[universe.Tree] = List()

母項後的括弧用於表示此類型為複合類型,即使沒有精緻化,我們也只想萃取與 with 關鍵字結合的類型順序。

在光譜的另一端是沒有明確父類的純粹精煉(又稱結構類型)

scala> val structural = tq"{ val x: Int; val y: Int }"
structural: universe.CompoundTypeTree =
scala.AnyRef {
  val x: Int;
  val y: Int
}

scala> val tq"{ ..$defns }" = structural
defns: List[universe.Tree] = List(val x: Int, val y: Int)

在這裡,我們可以看到 AnyRef 是如果我們沒有提供任何父類,則會隱式插入的父類。

存在類型

存在類型由類型樹和定義清單組成

scala> val tq"$tpt forSome { ..$defns }" = tq"List[T] forSome { type T }"
tpt: universe.Tree = List[T]
defns: List[universe.MemberDef] = List(type T)

或者,還有一個底線符號

scala> val tq"$tpt forSome { ..$defns }" = tq"List[_]"
tpt: universe.Tree = List[_$1]
defns: List[universe.MemberDef] = List(<synthetic> type _$1)

元組類型

類似於表達式,元組類型只是 TupleN 類別的語法糖

scala> val tup2 = tq"(A, B)"
tup2: universe.Tree = scala.Tuple2[A, B]

scala> val tq"(..$tpts)" = tup2
tpts: List[universe.Tree] = List(A, B)

類似地,Unit 類型被認為是零元組

scala> val tq"(..$tpts)" = tq"_root_.scala.Unit"
tpts: List[universe.Tree] = List()

重要的是要注意,對 Unit 參考進行模式匹配僅限於完全限定路徑或包含符號的參考。(請參閱 衛生

函數類型

類似於元組,函數類型是 FunctionN 類別的語法糖

scala> val funtype = tq"(A, B) => C"
funtype: universe.Tree = _root_.scala.Function2[A, B, C]

scala> val tq"..$foo => $bar" = funtype
foo: List[universe.Tree] = List(A, B)
bar: universe.Tree = C

此頁面的貢獻者