Sie den Typ direkt auf der empty
Methode angeben können, anstatt den zusätzlichen Satz von Pars/Klammern und die Art Anmerkung hinzuzufügen:
class Bar[A](set: Set[Foo[A]] = Set.empty[Foo[A]])
Was, warum die Typinferenz fehlschlägt, finden diese Fragen :
Update:
Ich entschuldige mich, meine hastige Antwort war weg. Das Problem in den obigen Beiträgen steht nicht wirklich mit diesem Problem in Zusammenhang. @TravisBrown hat in seinem Kommentar oben einen sehr guten Punkt gemacht. Dies scheint auf den ersten zu arbeiten:
class Bar[A](set: Set[A] = Set.empty)
Aber wenn Sie tatsächlich versuchen, den Konstruktor zu nennen es bei Verwendung vor Ort versagt:
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]
Dies deutet darauf hin, dass der Compiler nicht die Standardkonfiguration erzwingen Parameter gilt für alle A
, nur für einige A
. Sie haben wahrscheinlich, dass die Wahl, so dass Sie etwas tun können:
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))
jedoch jede Art von mit dem parametrisierten Typ Verschachtelung nicht bei der Deklaration Ort überprüfen geben im Konstruktor:
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)
Der Folgerung nicht scheitern, wenn der Typ-Parameter in einer kovarianten Position ist:
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
// ^
Diese werden zu arbeiten, weil der Compiler Nothing
als Co wählt Variantentyp standardmäßig.Das funktioniert gut für List
, aber das zweite Beispiel funktioniert nicht, wenn Sie tatsächlich versuchen, es aufzurufen.
Die Ursache der meisten dieser Seltsamkeit ist wahrscheinlich die Art, wie Scala Standardargumente behandelt. Der Compiler fügt dem Companion-Objekt automatisch eine zusätzliche Methode hinzu, und überall, wo Sie ein Argument auslassen, fügt der Compiler automatisch einen Methodenaufruf zu der neuen Methode im Companion-Objekt hinzu, um stattdessen das fehlende Argument zu generieren. Es sieht so aus, als würde das Abstrahieren des Standardarguments in eine Methode einige Dinge in der Typinferenz brechen, die mit einer normalen Zuweisung funktionieren würden.
Ich denke, dass die meisten dieser Ergebnisse ziemlich verwirrend sind. Was ich davon wegnehme, ist, dass es wichtig ist, deine Standardparameter zu testen, um sicher zu gehen, dass sie die Typkorrektheit nicht brechen, wenn du sie verwendest!
Keine Antwort, aber drei Dinge zu beachten: Sie könnten den Typparameter etwas anderes als 'A' nennen, um Verwechslungen mit dem (anderen)' A' in der gefundenen: [A] scala.collection zu vermeiden. unveränderlich.Set [A] 'Nachricht; Die wichtige Tatsache sowohl bei 'Set' als auch bei' Hallo' ist, dass sie invariant sind (im Gegensatz zu 'List'); und deine letzte Zeile kompiliert setzt vermutlich nicht was du willst. –
Während 'class Bar [A] (hallo: Hallo [A] = Hallo.apply)' wenn Sie es ändern, um 'Hallo.apply()' zu verwenden, funktioniert es gut. Du solltest die Parens auslassen können, also muss es hier wirklich durcheinander kommen. Es denkt, dass Sie die teilweise angewendete Funktion 'Hallo.Anwendung' übergeben, anstatt'Anwenden' ohne Argumente aufzurufen. (Die Fehlermeldung besagt, dass der Typ '[A]() Hallo [A]' gefunden wurde.) – DaoWen