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() }
^
- 编译器在第一种情况下看不到隐式,但在第二种情况下看到相同的隐式。为什么?
- 如何从伴随对象导入这个隐式对象?
这是类型推断的排序问题。还有其他类似的问题,不知道有没有一模一样的。
问题是,当 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?
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
:
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() }
^
- 编译器在第一种情况下看不到隐式,但在第二种情况下看到相同的隐式。为什么?
- 如何从伴随对象导入这个隐式对象?
这是类型推断的排序问题。还有其他类似的问题,不知道有没有一模一样的。
问题是,当 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?