在 GitHub 上編輯此頁面

交集類型 - 更多詳細資訊

語法

在語法上,類型 S & T 是中綴類型,其中中綴運算子為 &。運算子 & 是具有通常優先順序且受通常解析規則約束的常規識別碼。除非被另一個定義遮蔽,否則它會解析為類型 scala.&,該類型作為交集類型的內部表示的類型別名。

Type              ::=  ...| InfixType
InfixType         ::=  RefinedType {id [nl] RefinedType}

子類型規則

T <: A    T <: B
----------------
  T <: A & B

    A <: T
----------------
    A & B <: T

    B <: T
----------------
    A & B <: T

從上述規則,我們可以證明 &可交換的:對於任何類型 ABA & B <: B & A

   B <: B           A <: A
----------       -----------
A & B <: B       A & B <: A
---------------------------
       A & B  <:  B & A

換句話說,A & BB & A 是同種類型,因為這兩個類型具有相同的數值,並且是彼此的子類型。

如果 C 是協變或逆變類型建構函數,則可以使用下列規則簡化 C[A] & C[B]

  • 如果 C 是協變,則 C[A] & C[B] ~> C[A & B]
  • 如果 C 是反變的,則 C[A] & C[B] ~> C[A | B]

C 是協變的,則可以推導出 C[A & B] <: C[A] & C[B]

    A <: A                  B <: B
  ----------               ---------
  A & B <: A               A & B <: B
---------------         -----------------
C[A & B] <: C[A]          C[A & B] <: C[B]
------------------------------------------
      C[A & B] <: C[A] & C[B]

C 是反變的,則可以推導出 C[A | B] <: C[A] & C[B]

    A <: A                        B <: B
  ----------                     ---------
  A <: A | B                     B <: A | B
-------------------           ----------------
C[A | B] <: C[A]              C[A | B] <: C[B]
--------------------------------------------------
            C[A | B] <: C[A] & C[B]

擦除

S & T 的擦除類型是 ST 的擦除類型中擦除的 glb(最大下界)。交集類型的擦除規則如下所示的偽代碼

|S & T| = glb(|S|, |T|)

glb(JArray(A), JArray(B)) = JArray(glb(A, B))
glb(JArray(T), _)         = JArray(T)
glb(_, JArray(T))         = JArray(T)
glb(A, B)                 = A                     if A extends B
glb(A, B)                 = B                     if B extends A
glb(A, _)                 = A                     if A is not a trait
glb(_, B)                 = B                     if B is not a trait
glb(A, _)                 = A                     // use first

在上面,|T| 表示 T 的擦除類型,JArray 表示 Java 陣列的類型。

另請參閱:TypeErasure#erasedGlb

與複合類型(with)的關係

交集類型 A & B 取代了 Scala 2 中的複合類型 A with B。目前,語法 A with B 仍然允許,並解釋為 A & B,但將來會不建議將其用作類型(與在 newextends 子句中相反),並將其刪除。