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

  • captainpuppys2000

    captainpuppy

    20 HAZİRAN 2013
  • Karan Thakur

    Karan Thakur

    23 HAZİRAN 2010
  • Matthew Morrill

    Matthew Morr

    15 EKİM 2011