当前位置: 首页 > 知识库问答 >
问题:

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

慕凌
2023-03-14

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

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

共有3个答案

公羊伟志
2023-03-14

还有另一种(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

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

堵龙野
2023-03-14

实际上有一种方法可以完全满足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(a. k. a.Dotty(尽管这是编译器的名称)不是返回辅助的MyFunPart 2对象,而是可以直接返回带有隐式参数的函数值。这是因为Scala 3支持隐式函数(即参数隐含性现在是函数类型的一部分)。多个隐式参数列表变得如此容易实现,以至于语言可能会直接支持它们,尽管我不确定。

诸葛茂勋
2023-03-14

它们必须都在一个参数列表中,这个列表必须是最后一个。

def myfun(arg:String)(implicit p1: String, p2:Int)={} 
 类似资料:
  • 我是相当新的JNI善良,所以请告诉我,如果我是愚蠢的。 我试图将一个自定义异常从C扔到Java层,该层由字符串和整数构成。我无法让ThrowNew()工作,因为它只需要一个字符串参数。我能找到的每个自定义异常的例子都使用ThrowNew()!!Grrrrr 我猜我需要构造一个,并用“扔(jthrowable obj)”扔出去,但我不确定...这和“扔新()”一样吗?? 例如,这就是我需要的: 如果

  • 问题内容: 我在将控制器中定义的函数与指令中的回调函数绑定时遇到一些麻烦。我的代码如下所示: 在我的控制器中: 然后我的指令: 在我的html页面中: 上面的代码没有运气。根据我在各种教程中所读的内容,我知道我应该在HTML页面中指定参数? 问题答案: 您的代码中有一个小错误,请尝试以下代码,它应该对您有用

  • 问题内容: Java具有: 如何在Scala中实现相同的功能?也就是说,将不确定数量的参数传递给方法? 问题答案: 给出一个数组。将变量参数参数作为最后一个形式参数。

  • 大家好,我有这样的问题: 它说: 隐式类必须有一个主构造函数,并且在def traverseFilteringErrors的第一个参数列表中只有一个参数 和 类型不匹配。必填:Future[B] = 我是新来的scala,所以我应该怎么做来解决这个问题?

  • 可以使用零个或多个参数定义Clojure函数。 传递给函数的值称为arguments ,参数可以是任何类型。 参数的数量是函数的arity。 本章讨论了一些具有不同arities的函数定义。 在以下示例中,函数demo使用每个函数定义的多个参数进行定义。 (defn demo [] (* 2 2)) (defn demo [x] (* 2 x)) (defn demo [x y] (* 2 x y