特質參數
Scala 3 允許特質有參數,就像類別有參數一樣。
trait Greeting(val name: String):
def msg = s"How are you, $name"
class C extends Greeting("Bob"):
println(msg)
在初始化特質之前,會立即評估特質的引數。
特質參數的一個潛在問題是如何防止歧義。例如,您可能會嘗試使用不同的參數來擴充 Greeting
兩次。
class D extends C, Greeting("Bill") // error: parameter passed twice
這應該印出「Bob」還是「Bill」?事實上,這個程式是非法的,因為它違反了特質參數的第二個規則
-
如果類別
C
擴充參數化特質T
,而其超類別沒有,則C
必須傳遞引數給T
。 -
如果類別
C
擴充參數化特質T
,而其超類別也有,則C
不能傳遞引數給T
。 -
特質絕不可將參數傳遞給父特質。
以下是一個擴充參數化特質 Greeting
的特質。
trait FormalGreeting extends Greeting:
override def msg = s"How do you do, $name"
正如要求所述,沒有參數傳遞給 Greeting
。然而,在定義擴充 FormalGreeting
的類別時,這會造成問題
class E extends FormalGreeting // error: missing arguments for `Greeting`.
撰寫 E
的正確方式是同時擴充 Greeting
和 FormalGreeting
(順序不拘)
class E extends Greeting("Bob"), FormalGreeting
具有內容參數的特質
如果遺失的特質只包含 內容參數,則此「需要明確擴充」規則會放寬。在這種情況下,特質參考會隱含插入為具有推斷參數的附加父項。例如,以下是一個問候語變體,其中受話者是類型為 ImpliedName
的內容參數
case class ImpliedName(name: String):
override def toString = name
trait ImpliedGreeting(using val iname: ImpliedName):
def msg = s"How are you, $iname"
trait ImpliedFormalGreeting extends ImpliedGreeting:
override def msg = s"How do you do, $iname"
class F(using iname: ImpliedName) extends ImpliedFormalGreeting
最後一行中 F
的定義會隱含擴充為
class F(using iname: ImpliedName) extends
Object,
ImpliedGreeting(using iname),
ImpliedFormalGreeting
請注意插入的對未明確提及的超級特質 ImpliedGreeting
的參考。
參考
如需更多資訊,請參閱 Scala SIP 25。
本文中