Generisches Platzhalter in Variablendeklarationen in Scala
-
20-08-2019 - |
Frage
In Java könnte ich dies tun:
class MyClass {
private List<? extends MyInterface> list;
public void setList(List<MyImpl> l) { list = l; }
}
... unter der Annahme, dass (MyImpl implements MyInterface
) natürlich.
Was ist die analoge hierfür in Scala bei Verwendung eines Buffer
?
import java.lang.reflect._
import scala.collection.mutable._
class ScalaClass {
val list:Buffer[MyInterface] = null
def setList(l: Buffer[MyImpl]) = {
list = l
}
}
Das (natürlich) nicht kompiliert - aber wie erkläre ich die list
Variable so, dass es funktioniert
Bearbeiten ; Ich füge ein bisschen mehr. Der Unterschied ist offensichtlich etwas mit der Tatsache zu tun, dass in Java, Generika sind nie kovariant in T , während in Scala sie entweder covariant oder nicht sein können. Zum Beispiel wird die Scala Klasse List
in T (und notwendigerweise unveränderlich) kovariant. Daher ist die folgende kompilieren :
class ScalaClass {
val list:List[MyInterface] = null
def setList(l: List[MyImpl]) = {
list = l
}
}
Ich bin immer noch ein wenig mit dem Compiler-Fehler zu kämpfen:
Covariant type T occurs in contravariant position in ...
Zum Beispiel; dieser Compiler-Fehler tritt in der Klassendeklaration:
class Wibble[+T] {
var some: T = _ //COMPILER ERROR HERE!
}
Ich werde eine andere Frage stellen ...
Lösung
Der direkte Analog
import java.util.List;
List<? extends MyInterface> list;
ist
import java.util.List
var list : List[_ <: MyInterface] = _;
Same Deal mit Puffer
, um einen Kommentar zu antworten Sie earler gemacht, in Java-Typ-Parameter sind immer unveränderlich, nicht kovariant.
Andere Tipps
Ich bin nicht sicher, ob überhaupt Ich verstehe Ihre Frage (wahrscheinlich nicht genug Kaffee auf meiner Seite), aber es klingt wie Sie fragen, über generische Klassen . Wenn das nicht es ist, um einen Kommentar fallen lassen oder weitere Informationen zu Ihrer Frage hinzufügen und ich werde später überprüfen und meine Antwort bearbeiten.