Scala:找不到没有 val 的隐式,但是有 val 的隐式隐式

Scala: could not find implicit without val, but ambiguous implicits with val

Scala 版本:2.12.4.

比方说,有一个空特征和一个 class 函数,它接受特征实例作为隐式参数:

trait I

class A {
  def fa()(implicit i: I): Unit = {}
}

让我们定义另一个 class,它调用此 fa() 函数。我们将尝试从其伴生对象导入 I 实例:

class B(a: A) {
  import B._

  def fb(): Unit = { a.fa() }
}

object B {
  private implicit object II extends I
}

但是我们遇到了一个错误!

error: could not find implicit value for parameter i: I
         def fb(): Unit = { a.fa() }
                                ^

让我们在 class B:

中创建隐式 val
class B(a: A) {
  import B._

  private implicit val ii = II

  def fb(): Unit = { a.fa() }
}

突然,无论如何我们仍然面临错误:

error: ambiguous implicit values:
 both value ii in class B of type => B.II.type
 and object II in object B of type B.II.type
 match expected type I
         def fb(): Unit = { a.fa() }
                                ^
  1. 编译器在第一种情况下看不到隐式,但在第二种情况下看到相同的隐式。为什么?
  2. 如何从伴随对象导入这个隐式对象?

这是类型推断的排序问题。还有其他类似的问题,不知道有没有一模一样的。

问题是,当 class B 进行类型检查时,object B 上的类型推断尚未 运行。在第二个示例中 class B 的正文中使用 II 会触发此类型推断并使其显示为 implicit I.

可以通过将伴生对象放在 class 之前来解决,或者通过给 II 明确类型来解决,例如

object B {
  private implicit val II: I = new I {}
}

参见例如Why does this explicit call of a Scala method allow it to be implicitly resolved?