Scala : 'implizit' und type-parameter
Bin ich ein wenig Schwierigkeiten zu verstehen, das folgende Phänomen:
trait Trait[A] {
def traitType: String
}
object Trait {
implicit val stringTrait: Trait[String] = new Trait[String] {
def traitType: String = "string"
}
implicit val intTrait: Trait[Int] = new Trait[Int] {
def traitType: String = "int"
}
}
class Media[A] {
//works
def mediaType(implicit t: Trait[A]): String = t.traitType
//does not compile
def mediaType: String = implicitly[Trait[A]].traitType
}
object Main {
def main(args: Array[String]) {
val a = new Media[String]
val b = new Media[Int]
println(a.mediaType)
println(b.mediaType)
}
}
In der obigen snippet zeige ich 2 verschiedene Implementierungen mediaType Methode (ich habe einen Kommentar von Ihnen beim kompilieren des Codes). Allerdings die version mit den implizit nicht kompilieren? Ich bekomme folgende Fehlermeldung:
impl.scala:19: error: could not find implicit value for parameter e: Trait[A]
def mediaType: String = implicitly[Trait[A]].traitType
^
one error found
Ich verstehe, dass es gibt keine implizite Wert der Eigenschaft[A] verfügbar. Ich verstehe nicht, warum Ein nicht aufgelöst werden, um die Art von Medien wird instanziiert mit. Ich glaube, ich bin zu viel denken, in Bezug auf die C++ - Vorlagen hier und ich wäre sehr dankbar wenn jemand könnte mir einen Zeiger in die richtige Richtung.
Grüße,
raichoo
Du musst angemeldet sein, um einen Kommentar abzugeben.
Compiler muss beweisen, dass es existiert implizite
Trait
Instanz für dieA
. Im erstenmediaType
Umsetzung erklären Sie diese Anforderung. Aber in der zweiten Durchführung, aus der compiler-Sicht es gibt keine solche Garantie. So, damit es funktioniert, sollten Sie Fragen den NutzerMedia
Klasse zu geben. Sie können diese mit Kontext gebunden:Dies kann auch geschrieben werden mehr explizit:
So, in anderen Worten default-Konstruktor erfordert implizite
evidence
und Benutzer nicht in der Lage wäre zu instanziierenMedia
Klasse ohne Sie (explizit oder implizit).Wenn Sie möchten, diese version zu kompilieren:
dann die implizite Instanz von
Trait[A]
muss übergeben werden, z.B. wenn eine neue Instanz vonMedia
erstellt. Versuchen Sie zu definierenMedia
wie folgt statt:Eine fast gleichwertige definition mit einem Kontext-gebunden ist:
Dass gesagt wird, wenn das, was Sie versuchen zu tun ist, halten Sie weitere Informationen über den Typ-parameter eines parametrisierten Typs, die Sie verwenden möchten, können
Manifest
s anstelle Ihres eigenen Mechanismus. Sie würden Sie mit voller Art von Informationen aufA
zur Laufzeit, auch wennA
selbst einen parametrisierten Typ: