Berikut adalah beberapa alasan untuk menggunakan metode sederhana yang menyenangkan implicitly
.
Untuk memahami / memecahkan masalah Tampilan Tersirat
Tampilan Tersirat dapat dipicu ketika awalan suatu seleksi (pertimbangkan misalnya, the.prefix.selection(args)
tidak mengandung anggota selection
yang berlaku untuk args
(bahkan setelah mencoba untuk mengkonversi args
dengan Tampilan Tersirat). Dalam kasus ini, kompiler mencari anggota tersirat, ditentukan secara lokal dalam lingkup saat ini atau melampirkan, diwariskan, atau diimpor, yang merupakan Fungsi dari jenis yang the.prefix
ke jenis dengan selection
metode implisit yang ditetapkan, atau setara.
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
Tampilan Tersirat juga dapat dipicu ketika ekspresi tidak sesuai dengan Tipe yang Diharapkan, seperti di bawah ini:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
Di sini kompiler mencari fungsi ini:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
Mengakses Parameter Tersirat Diperkenalkan oleh Batas Konteks
Parameter implisit merupakan fitur Scala yang lebih penting daripada Tampilan Implisit. Mereka mendukung pola kelas tipe. Pustaka standar menggunakannya di beberapa tempat - lihat scala.Ordering
dan bagaimana menggunakannya SeqLike#sorted
. Parameter implisit juga digunakan untuk melewati manifest Array, dan CanBuildFrom
instance.
Scala 2.8 memungkinkan sintaks steno untuk parameter implisit, yang disebut Batas Konteks. Secara singkat, metode dengan parameter tipe A
yang memerlukan parameter tipe implisit M[A]
:
def foo[A](implicit ma: M[A])
dapat ditulis ulang sebagai:
def foo[A: M]
Tapi apa gunanya melewati parameter implisit tetapi tidak menamainya? Bagaimana ini bisa berguna ketika menerapkan metode ini foo
?
Seringkali, parameter implisit tidak perlu dirujuk secara langsung, itu akan diteruskan sebagai argumen implisit ke metode lain yang disebut. Jika diperlukan, Anda masih bisa mempertahankan tanda tangan metode singkat dengan Bound Konteks, dan panggilan implicitly
untuk mewujudkan nilai:
def foo[A: M] = {
val ma = implicitly[M[A]]
}
Melewati sebagian parameter implisit secara eksplisit
Misalkan Anda memanggil metode yang cukup mencetak seseorang, menggunakan pendekatan berbasis kelas tipe:
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)
Bagaimana jika kita ingin mengubah cara nama itu dihasilkan? Kami dapat secara eksplisit memanggil PersonShow
, secara eksplisit melewati alternatif Show[String]
, tetapi kami ingin kompiler untuk lulus Show[Int]
.
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
Implicitly
tersedia dalam Scala 2.8 dan didefinisikan dalam Predef sebagai:Biasanya digunakan untuk memeriksa apakah nilai implisit tipe
T
tersedia dan mengembalikannya jika memang demikian.Contoh sederhana dari presentasi retronym :
sumber
implicitly[Ordering[(Int, String)]].compare( (1, "b"), (1, "a") )
, khususnya untuk mengambil parameter implisit yang diperkenalkan oleh Context Bound:def foo[A: Ordering](a1: A, a2: A) = implicitly[Ordering[A]].compare(a1, a2)
Jawaban "mengajarkan Anda untuk menangkap ikan" adalah dengan menggunakan indeks anggota alfabet yang saat ini tersedia di Scaladoc nightlies . Huruf (dan
#
, untuk nama non-alfabet) di bagian atas panel paket / kelas adalah tautan ke indeks untuk nama anggota yang dimulai dengan huruf itu (di semua kelas). Jika Anda memilihI
, misalnya, Anda akan menemukanimplicitly
entri dengan satu kejadian, diPredef
, yang dapat Anda kunjungi dari tautan di sana.sumber
implicit
tampaknya menjadi fitur bahasa yang penting di Scala, dan jelas layak untuk penjelasan yang tepat. Berpikir bahwa dokumen yang hanya merinci hitungan jenis tanda tangan tampaknya lebih seperti kepuasan diri intelektual, daripada jawaban yang tulus. Lihat pertanyaan spesifik yang diajukan oleh OP - apa itu, dan bagaimana menggunakannya? Tidak dijawab oleh ini, atau dalam dokumen malam yang Anda bahkan tidak memberikan tautan sebenarnya. scala-lang.org/files/archive/nightly/docs/library/… Ini tidak mengajarkan apa-apa. Lihat Niklaus Wirth atau Turbo Pascal untuk contoh dokumen asli. -1implicit
danimplicitly
terkait, tetapi sangat berbeda. Kataimplicit
kunci adalah bagian dari bahasa.implicitly
didefinisikan dalam kode Scala biasa di perpustakaan standar. Karena dokumen on-line menyertakan tautan sumber, saya yakin masih lebih baik untuk merujuk kuesioner ke dokumen-dokumen tersebut dan sumber yang ditautkan.