Scala 当假定的等效隐式类不存在时,将应用隐式转换

Scala 当假定的等效隐式类不存在时,将应用隐式转换,scala,implicit-conversion,implicit,Scala,Implicit Conversion,Implicit,我有一个相当简单的例子,其中一个函数foo(),它接受类型为A的隐式参数,试图调用另一个函数bar(),它接受类型为B的隐式参数。在我遇到这个问题的项目中,B包含a功能的一个子集,因此我想提供从a到B的隐式转换,以使本例中的情况无缝 使用隐式转换B实现此功能。隐式转换()工作正常。scalac2.13.0接受以下代码: trait A trait B object B { // implicit class ImplicitClass(value: A) extends B imp

我有一个相当简单的例子,其中一个函数
foo()
,它接受类型为
A
的隐式参数,试图调用另一个函数
bar()
,它接受类型为
B
的隐式参数。在我遇到这个问题的项目中,
B
包含
a
功能的一个子集,因此我想提供从
a
B
的隐式转换,以使本例中的情况无缝

使用隐式转换
B实现此功能。隐式转换()
工作正常。
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) = ???
}
奇怪的是,使用隐式类
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

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

隐式类
等效于

class ImplicitClass(value: A) extends B

implicit def ImplicitClass(value: A): ImplicitClass
您可以看到不同之处:此隐式转换将
值:A
作为显式参数,与
def implicitConversion
不同。如果你改成

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

您将看到它的工作。

隐式类仅用于扩展方法,而不用于隐式转换,因为在它必须查找隐式的地方,您没有直接调用
B
类的任何方法,因此它没有被使用。其中,将应用隐式转换。-请注意,出于非常好的原因,不鼓励隐式转换。如果您改为这样做会更好。
trait A扩展了B
。这样,如果你有一个
A
的实例,它可以用于根据里斯科夫原理预期A
B
的地方。@LuisMiguelMejíaSuárez 1。不,它们可以用于隐式转换。2.“您没有直接调用B类的任何方法”,但预期的类型是
B
,这可能会触发隐式转换。