我有以下代码:
case class Number (value:Int)
和
class Calculator {
def performCalc( input:Number)(implicit calc: (Number=>Number) ) = calc(input)
}
现在,当我在specs2测试中试试这个:
class CalculatorTest extends mutable.Specification {
"Calculator" should {
"* Accept explicit calculation parameter" in {
implicit val addTwelve = (input: Number) => Number(input.value + 12)
val calc = new Calculator()
val result = calc.performCalc(Number(4))
result must beEqualTo(16)
}
}
}
我希望'addTwelve'函数隐式注入performCalc的参数。但是,我得到以下失败:
Error:(49, 42) ambiguous implicit values:
both method $conforms in object Predef of type [A]=> <:<[A,A]
and value addTwelve of type nl.example.Number => nl.example.Number
match expected type nl.example.Number => nl.example.Number
val result = calc.performCalc(Number(4))
^
我做错了什么?应该可以使用方法作为暗示,对吧?
斯卡拉:2.11.7
答案 0 :(得分:1)
是的,这在技术上是对隐式的有效使用,但它不是一个非常强大的用例。具体来说,有一个预先存在的隐含提供Number =&gt; Number。编译器无法确定您真正想要的隐式方法。
最好将此方法作为隐式类型的“标记”包装到特征中。
case class Number(value: Int)
trait CalcMethod {
def perform(n: Number): Number
}
class Calculator {
def performCalc(input:Number)(implicit calc: CalcMethod) = calc.perform(input)
}
class CalculatorTest extends mutable.Specification {
"Calculator" should {
"* Accept explicit calculation parameter" in {
implicit val addTwelve: CalcMethod = new CalcMethod {
def perform(input: Number) = Number(input.value + 12)
}
val result = new Calculator().performCalc(Number(4))
result must beEqualTo(16)
}
}
}
修改强>
这可能更接近你想要的东西:
case class Number(value: Int)
implicit class CalcMethod(val perform: Number => Number)
class Calculator {
def performCalc(input:Number)(implicit calc: CalcMethod) = calc.perform(input)
}
然后你可以像这样使用它:
implicit val addTwelve: CalcMethod = (input: Number) => Number(input.value + 12)
val result = new Calculator().performCalc(Number(4))