Nasıl Scala içinde implicits zinciri miyim?
Pimp-my-kütüphane desen bana, mevcut görünen bu yöntemi uygulayan bir sınıf örtülü bir dönüştürme yaparak bir sınıf için bir yöntem eklemek için izin verir.
Scala izin vermez böyle iki örtülü dönüşüm yaşanıyor, ancak, bunu yapamam var A
C
örtülü A
B
ve başka bir örtülü B
C
. Bu kısıtlama etrafında bir yolu var mı?
CEVAP
Scala yöntemler bulmaya birden fazla dönüştürme geçerli olmayacak olan bir yöntem eklemek için otomatik dönüşüm bir kısıtlama var. Örneğin:
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
}
// This demonstrates implicit conversion chaining restrictions
object T1 { // to make it easy to test on REPL
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)
// won't work
println(5.total)
println(new A(5).total)
// works
println(new B(5, 5).total)
println(new C(5, 5, 10).total)
}
EDİT: sınırları ('&;% lt') 2.11 https://issues.scala-lang.org/browse/SI-7629 Scala beri onaylanmaz . Görünüm (Tip sınıflar yerine kullanabilirsiniz)
Eğer örtülü bir tanım örtülü bir parametre gerektirir ancak, kendisi(Görünüm) bağlı, Scalasürece gerektiği gibi için ek örtülü değerleri arar. Son örnekten devam:
// def m[A <% B](m: A) is the same thing as
// def m[A](m: A)(implicit ev: A => B)
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)
// works
println(5.total)
println(new A(5).total)
println(new B(5, 5).total)
println(new C(5, 5, 10).total)
}
"Büyü!", diyebilirsiniz. Çok değil. Derleyici her biri anlamına gelir.
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)
// Scala won't do this
println(bToC(aToB(toA(5))).total)
println(bToC(aToB(new A(5))).total)
// Just this
println(bToC(new B(5, 5)).total)
// No implicits required
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)
// Scala does this
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)
// no implicits required
println(new C(5, 5, 10).total)
}
bToC
örtülü bir dönüşüm olarak kullanılıyor ise aToB
toA
olarak kabul ediliyorkapalı parametreleri, zincirlenmek yerine örtülü dönüşüm.
EDİT
İlgi çekici bir soru ile ilgili
Nasıl ve Scala içinde bir JSON dize ya...
Nasıl Python fonksiyonu dekoratörler z...
Nasıl bir proje içinde tek bir dosya i...
Nasıl böyle büyük mükafat içinde birde...
Nasıl bir Django queryset filtre içind...