Scala hat eine Einschränkung für automatische Konvertierungen zum Hinzufügen einer Methode. Dies bedeutet, dass beim Versuch, Methoden zu finden, nicht mehr als eine Konvertierung angewendet wird. Zum Beispiel:
class A(val n: Int)
class B(val m: Int, val n: Int)
class C(val m: Int, val n: Int, val o: Int) {
def total = m + n + o
}
object T1 {
implicit def toA(n: Int): A = new A(n)
implicit def aToB(a: A): B = new B(a.n, a.n)
implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n)
println(5.total)
println(new A(5).total)
println(new B(5, 5).total)
println(new C(5, 5, 10).total)
}
BEARBEITEN: Ansichtsgrenzen ('<%') sind seit Scala 2.11 veraltet. Https://issues.scala-lang.org/browse/SI-7629 (Sie können stattdessen Typklassen verwenden.)
Wenn jedoch eine implizite Definition einen impliziten Parameter erfordert selbst (Ansicht gebunden), Scala wird für zusätzliche implizite Werte für aussehen so lange wie nötig. Fahren Sie mit dem letzten Beispiel fort:
object T2 {
implicit def toA(n: Int): A = new A(n)
implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
println(5.total)
println(new A(5).total)
println(new B(5, 5).total)
println(new C(5, 5, 10).total)
}
"Magie!", Könnte man sagen. Nicht so. So würde der Compiler jeden einzelnen übersetzen:
object T1Translated {
implicit def toA(n: Int): A = new A(n)
implicit def aToB(a: A): B = new B(a.n, a.n)
implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n)
println(bToC(aToB(toA(5))).total)
println(bToC(aToB(new A(5))).total)
println(bToC(new B(5, 5)).total)
println(new C(5, 5, 10).total)
}
object T2Translated {
implicit def toA(n: Int): A = new A(n)
implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
println(bToC(5)(x => aToB(x)(y => toA(y))).total)
println(bToC(new A(5))(x => aToB(x)(identity)).total)
println(bToC(new B(5, 5))(identity).total)
println(new C(5, 5, 10).total)
}
Also, während bToC
es als implizite Konvertierung verwendet wird aToB
und toA
als implizite Parameter übergeben wird , anstatt als implizite Konvertierungen verkettet zu werden.
BEARBEITEN
Verwandte Frage von Interesse: