我不明白我在以下代码(Scala 2.9)中看到的明显矛盾的行为:
class Pimp1(val x : Double) {
def pluss(that : Pimp1) = x + that.x
def <(that : Pimp1) = x < that.x
}
object Pimp1 {
implicit def d2pimp(d : Double) = new Pimp1(d)
implicit def d2pimp(od : Option[Double]) = new Pimp1(od.get)
}
object Scratch2 extends App {
import Pimp1._
5.0.pluss(Some(5.0))
5.0 < Some(5.0)
}
'5.0.pluss(Some(5.0))' 行编译,但它后面的行没有编译并出现以下错误消息:
重载方法值 < 有替代方案: (x: Double)Boolean (x: Float)Boolean (x: Long)Boolean (x: Int)Boolean (x: Char)Boolean (x: Short)Boolean (x: Byte)Boolean 不能应用于 (Some[Double])
如果我将显式 < 运算符添加到采用 Option[Double] 的 Pimp 类中:
def <(that : Option[Double]) = x < that.get
一切都编译得很好。
现在,按照我理解 Scala 隐式转换规则的方式,这很有意义:
- 编译器知道 Double 上没有接受 Option[Double] 的 '<' 运算符
- 它考虑到 Pimp1 的隐式转换。
- 如果 Pimp1 有合适的运算符,它就会工作,否则会产生错误。
- 重要的是,这表明编译器不考虑应用第二个(可用的)隐式转换,从 Option[Double] 到 Pimp。
这就是我期望的工作方式。
但是,这似乎与第一个示例相矛盾,其中:
- 编译器发现 Double 上没有 pluss 方法。
- 编译器尝试隐式转换为 Pimp,它确实有这样的方法。
- 但是,为了使运算符工作,编译器必须对参数应用第二次隐式转换,以将其转换为 Pimp。
根据上面的逻辑,这不应该编译,但确实可以。隐式转换规则是否对不存在的方法和不匹配的方法有不同的处理?