从伴随对象导入隐式值但未使用

时间:2017-04-05 12:24:34

标签: scala implicit

我写了一些代码来获取伴侣对象中的一些隐含值,如下所示:

package example.implicits

class Test {
  import Test.GetValue
  import Test.Implicits._

  val intV = getV[Int]
  val stringV = getV[String]

  private def getV[T](implicit getV: GetValue[T]): T = getV.value
}

object Test {
  trait GetValue[T] {
    def value: T
  }

  object Implicits {
    implicit val intValue = new GetValue[Int] {
      def value = 10
    }

    implicit val stringValue = new GetValue[String] {
      def value = "ten"
    }
  }
}

这段代码无法编译,编译器抱怨它无法找到所需的隐含值。请注意我的环境是

  

Java HotSpot(TM)64位服务器VM上的scala 2.11.8,Java 1.8.0_66

但是,如果我明确使用这些值,则不会出错:

class Test {
  import Test.GetValue
  import Test.Implicits._

  val intV = getV[Int](intValue)
  val stringV = getV[String](stringValue)

  private def getV[T](implicit getV: GetValue[T]): T = getV.value
}

此外,如果我声明新隐式值如下:

class Test {
  import Test.GetValue
  import Test.Implicits._

  implicit val intValue1 = intValue

  implicit val stringValue1 = stringValue

  val intV = getV[Int]
  val stringV = getV[String]

  private def getV[T](implicit getV: GetValue[T]): T = getV.value
}
由于模糊的隐含值,会引发错误。

当我交换Test类和对象Test的位置时,一切顺利:

object Test {
  trait GetValue[T] {
    def value: T
  }

  object Implicits {
    implicit val intValue = new GetValue[Int] {
      def value = 10
    }

    implicit val stringValue = new GetValue[String] {
      def value = "ten"
    }
  }
}

class Test {
  import Test.GetValue
  import Test.Implicits._

  val intV = getV[Int]
  val stringV = getV[String]

  private def getV[T](implicit getV: GetValue[T]): T = getV.value
}

那么为什么在我已经在第一种情况下导入隐藏值后,scala能否找到隐含值?

当我换掉他们的位置时为什么会这样做?

1 个答案:

答案 0 :(得分:5)

那是因为编译器在解析Test.intValue中的隐含时尚未推断getV[Int]的类型。

明确提供Test.intValueTest.stringValue类型,您的问题就会得到解决。

我在某个地方读过(抱歉,无法记住确切的位置),隐式定义应该始终给出一个明确的类型,特别是为了避免这种行为。