当假设等效的隐式 class 不是时,应用隐式转换

Implicit conversion is applied when supposedly equivalent implicit class is not

我有一个相当简单的例子,其中一个函数 foo() 接受类型 A 的隐式参数,试图调用另一个函数 bar(),它接受类型的隐式参数输入 B。在我运行这个问题的项目中,B包含A的一个子集的功能,所以我想提供一个隐式转换AB 使此示例中的案例无缝衔接。

使用隐式转换 B.implicitConversion() 实现这一点按预期工作。 scalac 2.13.0 接受以下代码:

trait A

trait B

object B {
  // implicit class ImplicitClass(value: A) extends B

  implicit def implicitConversion(implicit se: A) = ???
}

class Test {
  def foo()(implicit a: A) = bar()

  def bar()(implicit b: B) = ???
}

奇怪的是,使用 隐式 class ImplicitClass 实现转换不起作用(通过删除 implicitConversion() 的定义并添加ImplicitClass 的定义)。该代码被 scalac:

拒绝
$ scalac 'Test.scala:12: error: could not find implicit value for parameter b: B
def foo()(implicit a: A) = bar()
^
one error found

我会假设在这种情况下隐式 classes 和隐式转换是可以互换的。我在这里遗漏了什么,为什么提供转换的两种方式不等效?

ImplicitClass 等同于

class ImplicitClass(value: A) extends B

implicit def ImplicitClass(value: A): ImplicitClass

您可以看到区别:此隐式转换将 value: A 作为 显式 参数,这与您的 def implicitConversion 不同。如果您更改为

def foo()(implicit a: A) = bar()(a)

你会看到它起作用。