Если бы это был класс, синтаксис был бы class MyClass () (неявный p1: String, неявный p2: Int) {}
skjagini
2
На самом деле есть способ сделать именно то, что требует OP. Немного запутано, но работает.
classMyFunPart2(arg: String, /*Not implicit!*/ p1: String) {
defapply(implicit p2: Int) = {
println(arg+p1+p2)
/* otherwise your actual code */
}
}
defmyFun(arg: String)(implicit p1: String): MyFunPart2= {
newMyFunPart2(arg, p1)
}
implicitval iString= " world! "implicitval 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 Tuple2defmyFun(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) Tuplesimplicitdefidis(implicit is: String, ii: Int): (String,Int)= (is,ii)
implicitdefidi(s: String)(implicit ii: Int): (String,Int)= (s,ii)
// The basic implicit values for both underlying parametersimplicitval iString = " world! "implicitval 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, implicitdefids(i: Int)(implicit is: String)= (is,i)
// we can even do
myFun("Hello")(2020)
// , and output is:// Hello world! 2020
Использование кортежа в качестве базового представления для параметров не является хорошей идеей, поскольку неявные преобразования могут мешать другим применениям. Собственно, неявные преобразования в любой стандартный тип (в том числе библиотечные) обычно создают проблемы в любом нетривиальном приложении. Решение состоит в том, чтобы создать специальный класс case для хранения параметров вместо Tuple. Важным преимуществом является то, что им можно было бы дать имена более значимые, чем _1 и _2.
Ответы:
Все они должны входить в один список параметров, и этот список должен быть последним.
def myfun(arg:String)(implicit p1: String, p2:Int)={}
источник
На самом деле есть способ сделать именно то, что требует 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.
источник