在Scala中定义具有多个隐式参数的函数


94

如何定义具有多个隐式参数的函数。

def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work

2
在问题文本中,您正在询问功能。在您的代码段中,您有一个方法。您是在问函数还是方法?
约尔格W¯¯米塔格

Answers:


190

它们必须全部放在一个参数列表中,并且该列表必须是最后一个。

def myfun(arg:String)(implicit p1: String, p2:Int)={} 

1
如果它是一个类,则语法将为MyClass()(隐式p1:字符串,隐式p2:Int){}
skjagini

2

实际上,有一种方法可以完全满足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支持“隐式函数”(即“参数隐式”现在是函数类型的一部分)。多个隐式参数列表变得如此易于实现,以至于语言可能直接支持它们,尽管我不确定。


1

还有另一种(IMO更简单,更灵活)的方式来达到类似的效果:

// 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

使用元组作为参数的基础表示不是一个好主意,因为隐式转换可能会干扰其他用途。实际上,对任何标准类型(包括库类型)的隐式转换通常会在任何非平凡的应用程序中造成麻烦。解决方案是创建一个专用的案例类来保存参数,而不是元组。一个重要的优点是,可以给它们指定比_1和_2更有意义的名称。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.