Scala隐式转换冲突很奇怪

时间:2018-12-21 09:24:36

标签: scala implicit

我发现了一个奇怪的编译错误:

class A
class B

object M {
  implicit val mA: M[A] = d => new A
  implicit val mB: M[B] = d => new B
}

trait M[K] {
  def get(d: D): K
}

object D {
  implicit def f[K](d: D)(implicit m: M[K]): K = m.get(d)
}

class D

object Main {
  val d = new D
  val a: A = d // This line can't compile!
}

由于mAmB冲突导致无法编译。 但这很奇怪,因为类型B与我们的结果类型不匹配。

如果我这样评论mB

class A
class B

object M {
  implicit val mA: M[A] = d => new A
  //implicit val mB: M[B] = d => new B
}

trait M[K] {
  def get(d: D): K
}

object D {
  implicit def f[K](d: D)(implicit m: M[K]): K = m.get(d)
}

class D

object Main {
  val d = new D
  val a: A = d // can compile
}

可以编译。为什么第一种情况不能编译?

1 个答案:

答案 0 :(得分:3)

之所以发生这种情况,是因为当编译器尝试查找隐式变量以m传递给f时,它不知道预期的返回类型(因为它取决于将选择哪个隐式变量)。它创建了一种循环依赖。

PS:您无需使f隐式说明这一问题。