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
如果我尝试对自己的类型做同样的事情,将 Float
和 Double
分别替换为 MyFloat
和 MyDouble
,则 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 的情况。)
我已经定义了一个隐式 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
如果我尝试对自己的类型做同样的事情,将 Float
和 Double
分别替换为 MyFloat
和 MyDouble
,则 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 的情况。)