【问题标题】:Scala: could not find implicit without val, but ambiguous implicits with valScala:没有 val 就找不到隐含,但 val 却模棱两可
【发布时间】:2018-02-15 08:03:00
【问题描述】:

Scala 版本:2.12.4。

假设有一个空 trait 和一个带有函数的类,它接受 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. 如何从伴生对象中导入这个隐式对象?

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    这是类型推断的排序问题。还有其他类似的问题,不知道有没有完全相同的问题。

    问题是当class B 被类型检查时,类型推断还没有在object B 上运行。在第二个示例中,在 class B 的主体中使用 II 会触发这种类型推断,并使其作为 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?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      • 2012-07-08
      • 1970-01-01
      • 2020-10-22
      • 1970-01-01
      相关资源
      最近更新 更多