Scala:具有相同声明的两个隐式参数

时间:2011-10-31 18:18:30

标签: scala arguments implicit

我有以下课程:

class Example(implicit doSomething1: (Double, Double) => Double, implicit doSomething2: (Double, Double) => Double)
{
  //..
}

如您所见,构造函数有两个具有相同声明的隐式参数(函数)。但我想“注入”两个不同的定义。这可能是隐含的吗?或者只能以已知的显式方式进行?

由于

2 个答案:

答案 0 :(得分:10)

如果编译器在隐式作用域中查找implicit (Double, Double) => Double,则要么只有一个具有更高优先级,并且它将同时选择一个,或者没有(在隐式作用域中根本没有,或者具有最高优先级的多个)并且缺少隐含值将会出错。

如果你想区分,你可能有两种不同的类型,都扩展了Function2 [Double,Double,Double]。例如

trait Addition extends Function[Double, Double, Double]
trait Multiplication extends Function[Double, Double, Double]
class Example(implicit addition: Addition, implicit multiplication: Multiplication) 

这可能是合理的,可以独立选择两种操作。如果两个选择需要一致,那么只有一个特征同时具有两个操作

可能更有意义
trait Ring {
  def add(x: Double, y: Double): Double
  def mult(x: Double, y: Double): Double
}
// or `case class Ring(
//       addition: (Double, Double) => Double, 
//       multiplication: (Double, Double) => Double)
class Example(implicit ring: Ring)

最后,只有在“自然地”在隐式范围内获得正确的操作时,所有这些才有用。如果你必须在每次创建一个例子时都隐含它们,比如在

implicit val addition = ...
implicit val multiplication = 
new Example

你也可以是明确的。

此外,如果预期大多数调用都使用相同的值,并且您只想更改其中的一些,则可能更愿意使用默认值

class Example(doSomething1 : (Double, Double) => Double = <default value>, doSomething2  ...)

你甚至可以同时使用默认值的隐式参数。如果这样做,则在未找到隐式时使用默认值。

答案 1 :(得分:0)

class Example(implicit doSomething1: (Double, Double) => Double, doSomething2: (Double, Double) => Double)
{
  //..
}

但是如果两个隐式参数具有相同的类型,它们显然会具有相同的值(您仍然可以显式传递不同的参数)。