Comment puis-je définir une fonction avec plusieurs arguments implicites.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Comment puis-je définir une fonction avec plusieurs arguments implicites.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Il existe en fait un moyen de faire exactement ce que le PO demande. C'est un peu compliqué, mais ça marche.
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
En Scala 3 (alias "Dotty", bien que ce soit le nom du compilateur), au lieu de renvoyer un auxiliaire MyFunPart2 il est possible de retourner directement une valeur de fonction avec des arguments implicites. En effet, Scala 3 prend en charge les "fonctions implicites" (c'est-à-dire que l'implicite des paramètres fait désormais partie des types de fonctions). Les listes de paramètres implicites multiples deviennent si faciles à implémenter qu'il est possible que le langage les supporte directement, bien que je n'en sois pas sûr.
Il existe un autre moyen (plus simple et plus souple, selon l'OMI) d'obtenir un effet similaire :
// 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
Utiliser un Tuple comme représentation sous-jacente des paramètres n'est pas une bonne idée car les conversions implicites pourraient interférer avec d'autres utilisations. En fait, les conversions implicites vers n'importe quel type standard (y compris ceux des bibliothèques) créent généralement des problèmes dans toute application non triviale. La solution consiste à créer une classe de cas dédiée pour contenir les paramètres au lieu d'un Tuple. Un avantage important est que l'on peut leur donner des noms beaucoup plus significatifs que _1 et _2.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
Dans le texte de la question, vous posez une question sur une fonction. Dans votre extrait de code, vous avez une méthode. S'agit-il d'une fonction ou d'une méthode ?