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

  • GOTO Conferences

    GOTO Confere

    3 EKİM 2011
  • Kupa World

    Kupa World

    1 EYLÜL 2011
  • MofoHifi Records

    MofoHifi Rec

    15 HAZİRAN 2006