无法注入Impicit功能

时间:2016-02-02 22:07:06

标签: scala function implicit

我有以下代码:

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

1 个答案:

答案 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))