簡體   English   中英

為什么 Scala 特征不允許構造函數參數?

[英]Why don't Scala traits allow constructor parameters?

我是 Scala 的新手,來自 Java,我只是在閱讀 traits。 經常提到的一件事是特征沒有(不能?不會?)具有構造函數參數。 我很想知道這是否有原因。

來自很久以前的數學/計算機科學背景,我想知道這是否是由於某些語言設計決定而不可避免的結果,或者這是否是避免某些繼承/混合問題或其他問題的有意識決定?

希望有人知道,因為感覺背后可能有一些有趣的東西。

其他答案描述了語言; 我懷疑您的問題可能真的是“為什么要這樣設計”。

我相信它源於擴展多個特征時會出現的笨拙和冗長,特別是使用覆蓋和類型以及各種混合策略。

蛋糕模式通常會導致各種特征以一種在混合類中完全不可見的方式相互提供缺失的位 - 按照設計 - 。 混合可以是雙向的,使用self 類型 因此,從特征構造類對於編譯器來說可能是一件非常麻煩的事情。 Scala 經常用編譯器設計和實現的簡單性來換取語言使用和代碼縮減的簡單性,這當然是一個很好的例子。

因此,雖然可能存在簡單的、分層的情況,其中構造函數可能有用且足夠,但對於更困難的、非分層的場景,它幾乎肯定必須是其他機制的冗余。

Scala 3 將允許特征參數。 這是文檔中的示例

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class C extends Greeting("Bob") {
  println(msg)
}

答案是:這就是 Scala 現在的樣子。

但在未來可能不是這樣:特征參數可以取代早期的初始化器。 (請參閱 Martin Odersky 最近的Scala Days演講第 34 頁) Scala:它從何而來,將向何處去

特征沒有構造函數參數,因為特征不能被構造。 給定任何特征T都不可能實例化任何類型為T對象。 你可以用 vals 覆蓋 trait defs,所以

trait Foo {
  def bar: String
}
class Baz(override val bar: String) extends Foo

您不能直接構造它們,因為new MyTrait {}實際上是new Object with MyTrait {}的匿名new Object with MyTrait {}類的糖

Scala 3 允許帶有參數的特征,就像類有參數一樣。

Trait 是 Java Interface 的模擬。 主要區別在於 trait 可以為它們的方法默認實現。

所以 Java 接口不能有構造函數,Scala 特征也是如此

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM