SORU
16 Mart 2011, ÇARŞAMBA


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
16 Mart 2011, ÇARŞAMBA


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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • alex maybury

    alex maybury

    20 Aralık 2007
  • Phandroid

    Phandroid

    26 Ocak 2009
  • picster

    picster

    20 NİSAN 2006