Wie verwenden von Scala singleton-Objekt-Typen?
Ich Schreibe eine Klasse dient als Basisklasse für eine Reihe von singleton-Objekten. In jeder singleton-Objekte, es wird vals repräsentieren bestimmte Eigenschaften, und ich will schreiben Sie eine Methode, die für jede singleton-Objekt, akzeptiert nur Objekte, die von ihm erstellt.
Also ich habe Folgendes:
class Obj[M <: Maker]
class Maker {
implicit val me: this.type = this
def make[M <: Maker](implicit maker: M) = new Obj[M]
def accept(obj: Obj[this.type]) = {...}
}
So weit, So gut. Dann möchte ich erklären, einer dieser singleton-Objekte:
object M extends Maker {
val a = make
}
Aber dann, wenn ich es versuchen:
M.accept(M.a)
dann bekomme ich einen compile-Zeit-Fehler:
type mismatch; found : com.test.Obj[object com.test.M] required: com.test.Obj[com.test.M.type]
Meine Fragen:
- Was ist der Typ
object com.test.M
, und wie unterscheidet es sich voncom.test.M.type
? - Wie kann ich dies in einer INTELLIGENTEREN Weg?
- für Punkt 2: es gibt immer die Möglichkeit, um
Obj
eine geschachtelte KlasseMaker
und entfernen Sie den type-parameter, aber ich möchte das nicht, da muss ich vorbei um Obj-Instanzen auf Objekte außerhalb der Klassen in meinem Beispiel, und ich brauche, um filter auf den Typ-parameter. - Könnten Sie bitte geben Sie eine kompilierbare Beispiel? Etwas, was ich kann kopieren&einfügen in eine REPL?
- Gute Frage: ich lief in das gleiche problem bei der Umsetzung einer HList und die Art der HNil abgeleitet wurde als Objekt HNil und nicht HNil.Typ. Upgrade auf 2.9 nightly-build und alles ist in Ordnung jetzt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bekommen mit der Zeit, mein guter Mann! Ich reparierte diese über 24 Stunden. Weiter erwarte ich, um zu sehen, Velociraptoren jagen dodos, wütend knacken den buggy Peitschen, während sich Börsenkurse auf Ihre pointcast Bildschirmschoner.
Den commit in Frage: http://lampsvn.epfl.ch/trac/scala/changeset/23622
object M
und gebenM.type
?Verwenden
this.type
stattM
. Dieses vereinfachte Beispiel sollte funktionieren:object com.text.M
undcom.text.M.type
?Ihre erste Frage, "Was ist der Typ
object com.test.M
, und wie unterscheidet es sich voncom.test.M.type
?", noch nicht beantwortet wurde. Ich habe es nicht gefunden, dokumentiert in der spec, aber es scheint, dass dieobject M
Typ ist der interne Typ repräsentiert die Klasse, die implizit erstellt, wenn Sie ein Objekt definierenM
. NatürlichM
ist die einzige Instanz der Klasse, so würde man erwarten, dass dieobject M
Typ äquivalent zuM.type
, aber der compiler anscheinend nicht so sehen.Des Problems, das Sie laufen in, als @retronym erklärt, ist, dass die singleton-Typ
M.type
ist nicht abgeleitet, für den type-parameter beim aufrufen Ihrermake
Methode. Dies ist aus dem gleichen Grund, dassString
abgeleitet, anstattv.type
in der Sitzung unter:wo
identity
ist definiert alsobject M
ist wirklichM.type
und es war ein Fehler, oder die Typ-Inferenz hat sich etwas geändert.val v = "string"
, v als Typ "String" und wenn Sie schreibenval singleton = M
, dann singleton-TypM.type
und nichtobject M
, so erwartete ich meine erste Beispiel funktioniert. Froh, dass es in 2.9Dies funktioniert:
Den geheimen "Soße" ist mit
make[M.type]
innerhalb der singleton-Objekt.@retronym verdient den Kredit für die Erklärung diese: Wie man richtig geben-kommentieren dieser HList?
[M.type]
beim Aufrufmake
ausM
...