Как я могу определить функцию с несколькими неявными аргументами.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Как я могу определить функцию с несколькими неявными аргументами.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Ответы:
На самом деле есть способ сделать именно то, что требует OP. Немного запутано, но работает.
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 (также известном как «Dotty», хотя это имя компилятора) вместо возврата вспомогательного объекта MyFunPart2 можно напрямую вернуть значение функции с неявными аргументами. Это связано с тем, что Scala 3 поддерживает «неявные функции» (т.е. «неявность параметров» теперь является частью типов функций). Несколько неявных списков параметров стало настолько легко реализовать, что, возможно, язык будет поддерживать их напрямую, хотя я не уверен.
Существует еще один (более простой и гибкий) способ добиться аналогичного эффекта:
// 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
Использование кортежа в качестве базового представления для параметров не является хорошей идеей, поскольку неявные преобразования могут мешать другим применениям. Собственно, неявные преобразования в любой стандартный тип (в том числе библиотечные) обычно создают проблемы в любом нетривиальном приложении. Решение состоит в том, чтобы создать специальный класс case для хранения параметров вместо Tuple. Важным преимуществом является то, что им можно было бы дать имена более значимые, чем _1 и _2.