聯合類型
聯合類型 A | B
包含兩種類型的所有值。
trait ID
case class UserName(name: String) extends ID
case class Password(hash: Hash) extends ID
def help(id: UserName | Password) =
val user = id match
case UserName(name) => lookupName(name)
case Password(hash) => lookupPassword(hash)
...
聯合類型是交集類型的對偶。|
是可交換的:A | B
與 B | A
為相同類型。
只有在明確給定聯合類型,或所有備選項式的共同超類別為透明時,編譯器才會將聯合類型指定給表達式。
這可以在以下 REPL 轉錄中看到
scala> val password = Password(123)
val password: Password = Password(123)
scala> val name = UserName("Eve")
val name: UserName = UserName(Eve)
scala> if true then name else password
val res1: ID = UserName(Eve)
scala> val either: Password | UserName = if true then name else password
val either: UserName | Password = UserName(Eve)
res1
的類型為 ID
,為 UserName
和 Password
的超類別,但不是最小超類別 UserName | Password
。如果我們想要最小超類別,我們必須明確給定,就像 either
的類型那樣。
如果宣告共用超特質 ID
為 transparent
,則推論行為會改變
transparent trait ID
在這種情況下,聯集類型不會擴大。
scala> if true then name else password
val res2: UserName | Password = UserName(Eve)
如果未明確宣告父類別就宣告 UserName
和 Password
,也會推論出更精確的聯集類型,因為在這種情況下,它們的隱含超類別為 Object
,而 Object
是假設為透明的類別之一。請參閱 透明特質和類別 以取得此類類別的清單。
case class UserName(name: String)
case class Password(hash: Hash)
scala> if true then UserName("Eve") else Password(123)
val res3: UserName | Password = UserName(Eve)