Birden çok örtük argüman içeren bir işlevi nasıl tanımlayabilirim?
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Birden çok örtük argüman içeren bir işlevi nasıl tanımlayabilirim?
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Yanıtlar:
Hepsi tek bir parametre listesine girmeli ve bu liste sonuncu olmalıdır.
def myfun(arg:String)(implicit p1: String, p2:Int)={}
Aslında OP'nin gerektirdiğini tam olarak yapmanın bir yolu var. Biraz kıvrık, ama işe yarıyor.
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
Scala 3'te ("Dotty" olarak da bilinir, ancak bu derleyicinin adıdır) yardımcı bir MyFunPart2 nesnesi döndürmek yerine, dolaylı olarak örtük argümanlarla bir işlev değeri döndürmek mümkündür. Bunun nedeni, Scala 3'ün "Örtük İşlevleri" desteklemesidir (yani "parametre örtüklüğü" artık işlev türlerinin bir parçasıdır). Birden çok örtük parametre listesinin uygulanması o kadar kolay hale geldi ki, emin değilim, ancak dilin bunları doğrudan desteklemesi mümkün.
Benzer bir etki elde etmenin başka (IMO daha basit ve daha esnek) bir yolu vardır:
// 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
Bir Tuple'ı parametrelerin temel temsili olarak kullanmak iyi bir fikir değildir çünkü örtük dönüştürmeler diğer kullanımları etkileyebilir. Aslında, herhangi bir standart türe (kitaplık dahil) örtük dönüştürmeler genellikle önemsiz olmayan uygulamalarda sorun yaratır. Çözüm, bir Tuple yerine parametreleri tutmak için özel bir durum sınıfı oluşturmaktır. Önemli bir avantaj, onlara _1 ve _2'den çok daha anlamlı isimler verilebilmesidir.