您可以在empty
方法直接指定類型,而不必添加額外的設置括號/括號和類型註釋:
class Bar[A](set: Set[Foo[A]] = Set.empty[Foo[A]])
至於爲什麼類型推斷失敗,看到這些問題:
更新:
我很抱歉,我匆忙的回答是路要走。上面的帖子中的問題與這個問題並沒有真正的關係。 @TravisBrown在他上面的評論中提到了一個很好的觀點。這似乎在第一工作:
class Bar[A](set: Set[A] = Set.empty)
但如果你真的嘗試調用它無法在使用現場的構造:
new Bar[Int]
// <console>:9: error: type mismatch;
// found : scala.collection.immutable.Set[Nothing]
// required: Set[Int]
// Note: Nothing <: Int, but trait Set is invariant in type A.
// You may wish to investigate a wildcard type such as `_ <: Int`. (SLS 3.2.10)
// Error occurred in an application involving default arguments.
// new Bar[Int]
這表明編譯器不強制默認參數對所有A
有效,僅適用於某些A
。他們大概做了這個選擇,所以你可以做這樣的事情:
scala> case class MyClass[T](set: Set[T] = Set(0))
defined class MyClass
scala> MyClass() // defaults to MyClass[Int]
res0: MyClass[Int] = MyClass(Set(0))
scala> MyClass(Set('x)) // but I can still use other types manually
res1: MyClass[Symbol] = MyClass(Set('x))
然而,任何形式的與參數化類型嵌套無法鍵入構造檢查在聲明的網站:
class Bar[A](set: Set[Option[A]] = Set.empty)
// <console>:7: error: polymorphic expression cannot be instantiated to expected type;
// found : [A]scala.collection.immutable.Set[A]
// required: Set[Option[?]]
// class Bar[A](set: Set[Option[A]] = Set.empty)
的因爲編譯器選擇Nothing
作爲共
class Bar[ A ](set: List[Foo[A]] = List.empty) // OK
class Bar[ A ](set: Map[Int,Foo[A]] = Map.empty) // OK (unless you use it)
class Bar[ A ](set: Map[Foo[A],Int] = Map.empty) // BAD
// <console>:8: error: polymorphic expression cannot be instantiated to expected type;
// found : [A, B]scala.collection.immutable.Map[A,B]
// required: Map[Foo[?],Int]
// class Bar[ A ](set: Map[Foo[A],Int] = Map.empty) // BAD
// ^
這些工作:推論不會失敗,如果類型參數是在協變位置變體類型默認。這適用於List
,但上面的第二個示例在您實際嘗試調用它時不起作用。
大部分這種奇怪的原因可能是Scala處理默認參數的方式。編譯器會自動爲伴隨對象添加一個額外的方法,然後無論您何時離開參數,編譯器都會自動將方法調用添加到伴隨對象中的新方法以生成缺少的參數。它看起來像將缺省參數抽象爲一個方法會破壞類型推斷中的一些東西,這些東西可以用於正常的賦值。
我認爲這些發現大部分都相當混亂。我從中獲得的是,實際測試默認參數非常重要,以確保在嘗試使用它們時不會破壞類型正確性!
不是答案,但需要注意三點:爲了避免與'found:[A] scala.collection中的(不同)'A'混淆,您可能想要指定類型參數而不是'A'。 immutable.Set [A]'message;關於'Set'和你的'Hallo'的重要事實是它們是不變的(而不是'List');你最後一行的編譯可能不會做你想要的。 –
雖然'class Bar [A](hallo:Hallo [A] = Hallo.apply)'如果你改變它使用'Hallo.apply()'它可以正常工作。你應該能夠離開這個parens,所以它在這裏一定會變得非常困惑。它認爲你正在傳遞部分應用的函數'Hallo.apply',而不是調用沒有參數的'apply'。 (錯誤消息說它發現類型'[A]()Hallo [A]'。) – DaoWen