Bagaimana saya bisa mendefinisikan fungsi dengan beberapa argumen implisit.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Bagaimana saya bisa mendefinisikan fungsi dengan beberapa argumen implisit.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Jawaban:
Mereka semua harus masuk dalam satu daftar parameter, dan daftar ini harus menjadi yang terakhir.
def myfun(arg:String)(implicit p1: String, p2:Int)={}
Sebenarnya ada cara untuk melakukan apa yang dibutuhkan OP. Sedikit berbelit-belit, tetapi berhasil.
class MyFunPart2(arg: String, /*Not implicit!*/ p1: String) {
def apply(implicit p2: Int) = {
println(arg+p1+p2)
/* otherwise your actual code */
}
}
def myFun(arg: String)(implicit p1: String): MyFunPart2= {
new MyFunPart2(arg, p1)
}
implicit val iString= " world! "
implicit val iInt= 2019
myFun("Hello").apply
myFun("Hello")(" my friend! ").apply
myFun("Hello")(" my friend! ")(2020)
// Output is:
// Hello world! 2019
// Hello my friend! 2019
// Hello my friend! 2020
Dalam Scala 3 (alias "Dotty", meskipun ini adalah nama kompiler) alih-alih mengembalikan objek MyFunPart2 tambahan , dimungkinkan untuk mengembalikan nilai fungsi dengan argumen implisit secara langsung. Ini karena Scala 3 mendukung "Fungsi Implisit" (yaitu "parameter implisit" sekarang adalah bagian dari jenis fungsi). Beberapa daftar parameter implisit menjadi sangat mudah untuk diterapkan sehingga mungkin bahasa akan mendukungnya secara langsung, meskipun saya tidak yakin.
Ada cara lain (IMO yang lebih sederhana dan lebih fleksibel) untuk mencapai efek serupa:
// Note the implicit is now a Tuple2
def myFun(arg: String)(implicit p: (String, Int) ): Unit = {
println(arg + p._1 + p._2)
/*otherwise your actual code*/
}
// These implicit conversion are able to produce the basic implicit (String,Int) Tuples
implicit def idis(implicit is: String, ii: Int): (String,Int)= (is,ii)
implicit def idi(s: String)(implicit ii: Int): (String,Int)= (s,ii)
// The basic implicit values for both underlying parameters
implicit val iString = " world! "
implicit val iInt = 2019
myFun("Hello")
myFun("Hello")(" my friend! ")
myFun("Hello")(" my friend! ",2020)
// Output is:
// Hello world! 2019
// Hello my friend! 2019
// Hello my friend! 2020
// If we add the following implicit,
implicit def ids(i: Int)(implicit is: String)= (is,i)
// we can even do
myFun("Hello")(2020)
// , and output is:
// Hello world! 2020
Menggunakan Tuple sebagai representasi dasar untuk parameter bukanlah ide yang baik karena konversi implisit dapat mengganggu penggunaan lain. Sebenarnya, konversi implisit ke tipe standar apa pun (termasuk yang pustaka) biasanya menimbulkan masalah dalam aplikasi non-sepele. Solusinya adalah membuat kelas kasus khusus untuk menampung parameter, bukan Tuple. Keuntungan penting adalah mereka bisa diberi nama yang jauh lebih bermakna daripada _1 dan _2.