Scala 数字类型的隐式转换是否特殊?

Are implicit conversions for Scala numeric types special?

我已经定义了一个隐式 class,它在 Double 的所有实例上提供了一个方法 foo。奇怪的是,现在也可以调用此方法,例如在 Float 个实例上,由 scalac 2.12.5(使用 -Xscript Foo)接受的以下示例显示:

implicit class DoubleOps(value: Double) {
  def foo: Double = value
}

val x: Float = 1f
val y = x.foo

如果我尝试对自己的类型做同样的事情,将 FloatDouble 分别替换为 MyFloatMyDouble,则 foo 不是在 MyFloat 个实例上可用。

trait MyDouble

object MyDouble {
  implicit class MyFloatAsMyDouble(value: MyFloat) extends MyDouble
}

trait MyFloat

implicit class MyDoubleOps(value: MyDouble) {
  def foo: MyDouble = value
}

val x: MyFloat = new MyFloat { }
val y = x.foo

$ scalac -Xscript Foo foo.scala
foo.scala:14: error: value foo is not a member of this.MyFloat
val y = x.foo
          ^
one error found

这符合我对编译器如何使用隐式搜索直接在类型上找不到的成员的理解。但为什么第一个例子仍然有效?

我认为这是 numeric widening achieved through weak conformance. (There is an active proposal to drop this from the language 的情况。)