Saya sedang berusaha untuk mempercepat Scala dan saya sedikit bingung tentang penggunaan kata kunci "implisit".

Saya pikir saya memahami gagasan parameter implisit, di mana parameter tidak secara eksplisit diteruskan, Scala akan mencari nilai dari tipe yang benar (dalam lingkup panggilan).

Saya bingung dengan penggunaan "val implisit".

Perhatikan cuplikan kode berikut:

case class DemoApp() {
   implicit val foo = CustomerFoo()
}

Apakah ini ada hubungannya dengan parameter yang diteruskan ke konstruktor kelas DemoApp()?

Bisakah seseorang tolong jelaskan?

Thx, John B

1
JohnB 2 Juli 2020, 02:10

1 menjawab

Jawaban Terbaik

pikir saya memahami gagasan parameter implisit, di mana parameter tidak secara eksplisit diteruskan,

Ini hanyalah sisi lain dari koin.

Scala akan mencari nilai dari jenis yang benar (dalam lingkup panggilan).

Ya, tetapi itu tidak hanya mengambil apa saja nilai acak. Hanya nilai yang secara eksplisit ditandai implicit.

Ada empat kegunaan pengubah implicit, yang terkait secara berpasangan.

Satu pasang terkait dengan parameter implisit. Ketika diterapkan ke parameter dalam daftar parameter, implicit berarti "argumen ini tidak perlu diberikan secara eksplisit, dapat dicari dalam konteks panggilan". Ketika diterapkan ke val atau object, pada gilirannya, itu berarti "nilai ini dapat diteruskan sebagai argumen implisit".

Pasangan lainnya terkait dengan konversi implisit. Ketika implicit diterapkan ke definisi metode dari metode dengan satu parameter, itu berarti "kapan pun Anda membutuhkan nilai tipe kembalian, tetapi Anda hanya memiliki nilai tipe parameter, Anda dapat menggunakan metode ini untuk mengonversi dari nilai argumen ke nilai kembalian".

Misalnya. jika saya memiliki sesuatu seperti ini:

implicit def string2Tuple2(s: String): (Int, Int) = {
  val l = s.split(",")
  (l(0).toInt, l(1).toInt)
}

Kemudian, setiap kali Scala mengharapkan (Int, Int), saya juga dapat memberikan String sebagai gantinya, dan Scala tahu bahwa ia dapat memanggil string2Tuple untuk mengonversinya:

val m = Map.empty[Int, Int]

m + "2,3"
//=> val res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3)

Ini tentu saja contoh yang bodoh. Contoh yang lebih berguna adalah idiom perkaya-perpustakaan saya, di mana kita membuat kelas baru yang menambah kelas yang ada dengan beberapa fungsi baru, dan kemudian memberikan konversi implisit dari tipe lama ke tipe yang diperkaya :

class HelloString(s: String) {
  val hello = "Hello " + s + " World"
}

implicit def string2HelloString(s: String) = new HelloString(s)

"beautiful".hello
//=> val res2: String = Hello beautiful World

Di sinilah penggunaan kedua untuk pengubah implicit masuk. Kelas implicit hanyalah gula sintaksis untuk kelas pembungkus + konversi implisit, artinya di atas persis sama dengan:

implicit class string2HelloString(s: String) {
  val hello = "Hello " + s + " World"
}

Itu dia, empat penggunaan pengubah implicit dalam dua pasangan terkait.

3
Jörg W Mittag 2 Juli 2020, 00:22