Scala:没有val就找不到隐含的东西,但是val

时间:2018-02-15 08:03:00

标签: scala implicit

Scala版本:2.12.4。

让我们说,有一个空特征和一个带有函数的类,它接受trait实例作为隐式参数:

trait I

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

让我们定义另一个类,它调用这个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() }
                                ^

让我们在课程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. 如何从伴侣对象导入此隐式对象?

1 个答案:

答案 0 :(得分:2)

这是类型推断的排序问题。还有其他类似的问题,我不知道是否有确切的重复。

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

可以通过将伴随对象放在类之前,或者通过将显式类型赋予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?