İşte en basit yöntemi kullanmak için birkaç neden implicitly
.
Örtülü Görünümleri anlamak / sorunlarını gidermek için
Bir Örtülü görüntüleme seçimin öneki (örneğin göz önüne aldığımızda tetiklenebilir, the.prefix.selection(args)
bir üye içermiyor selection
uygulanabilir args
(hatta dönüştürmek için çalışıyor sonra args
Örtülü Görünümler ile). Bu durumda, örtük üyeleri için derleyici görünüyor, yerel olarak tanımlı geçerli veya çevreleyen kapsamlarda, devralınan veya içe aktarılan, bunların türünden tanımlı veya eşdeğer örtük yöntemlere the.prefix
sahip bir türe işlevler selection
.
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
Örtülü Görünümler, bir ifade Beklenen Tür'e uymadığında aşağıdaki gibi de tetiklenebilir:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
Derleyici bu işlevi arar:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
Bağlama Bağımlı Bir Tanıtıcı Parametreye Erişme
Örtük parametreler muhtemelen Scala'nın Örtük Görünümlerden daha önemli bir özelliğidir. Tip sınıfı modelini desteklerler. Standart kütüphane bunu birkaç yerde kullanır - bakın scala.Ordering
ve nasıl kullanıldığı SeqLike#sorted
. Örtük Parametreler, Array bildirimlerini ve CanBuildFrom
örneklerini iletmek için de kullanılır .
Scala 2.8, Bağlam Sınırları adı verilen örtük parametreler için steno sözdizimine izin verir. Kısaca, A
örtük tür parametresi gerektiren bir tür parametresine sahip bir yöntem M[A]
:
def foo[A](implicit ma: M[A])
şu şekilde yeniden yazılabilir:
def foo[A: M]
Ancak örtük parametreyi geçirmenin, ancak adlandırmamasının anlamı nedir? Yöntemi uygularken bu nasıl faydalı olabilir foo
?
Genellikle, örtük parametrenin doğrudan belirtilmesine gerek yoktur, adı verilen başka bir yönteme örtük bir argüman olarak tünellenir. Gerekirse, Bağlama Yöntemi ile terse yöntemi imzasını koruyabilir implicitly
ve değeri gerçekleştirmeye çağırabilirsiniz :
def foo[A: M] = {
val ma = implicitly[M[A]]
}
Örtük parametrelerin bir alt kümesini açıkça geçirme
Sınıf sınıfına dayalı bir yaklaşım kullanarak bir kişiyi güzel bir şekilde bastıran bir yöntem çağırdığınızı varsayın:
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
Ya adın çıkış şeklini değiştirmek istersek ne olur? Açık bir şekilde arayabiliriz PersonShow
, açıkça bir alternatif geçirebiliriz Show[String]
, ancak derleyicinin anahtarını geçmesini istiyoruz Show[Int]
.
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)