Scala多次隐式转换?

时间:2012-10-04 16:08:58

标签: scala implicit-conversion

我不理解我在以下代码中看到的明显矛盾行为(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)
}

该行&#39; 5.0.pluss(Some(5.0))&#39;编译,但它后面的行不编译与以下错误消息:

  

重载方法值&lt; with alternatives:(x:Double)Boolean(x:Float)Boolean(x:Long)Boolean(x:Int)Boolean(x:Char)Boolean(x:Short)Boolean(x:Byte)布尔值不能应用于(一些[双])

如果我添加显式&lt; Pimp类的运算符采用Option [Double]:

def <(that : Option[Double]) = x < that.get

一切都很好。

现在,我理解Scala隐式转换规则的方式,这很有道理:

  1. 编译器明白没有&#39;&lt;&#39; operator on Double接受Option [Double]
  2. 它考虑隐式转换为Pimp1。
  3. 如果Pimp1有合适的操作符,则可以使用,否则会产生错误。
  4. 重要的是,这表明编译器考虑应用第二个(可用的)隐式转换,从Option [Double]到Pimp。
  5. 这就是我期望事情发挥作用的方式。

    然而,这似乎与第一个例子相矛盾,其中:

    1. 编译器发现Double上没有pluss方法。
    2. 编译器尝试隐式转换为Pimp,它确实有这样的方法。
    3. 但是,为了使运算符工作,编译器必须对参数应用第二个隐式转换,将其转换为Pimp。
    4. 根据上面的逻辑,这不应该编译,但确实如此。隐式转换规则是否以不同方式处理不存在的方法和不匹配的方法?

1 个答案:

答案 0 :(得分:5)

这对我有意义。第一个是有效的:

Double有一个pluss方法吗?不,我们可以隐含地将其转换为具有某种功能的东西吗?是。好的,现在我想应用pluss方法。是否需要选项?不能。我可以将Option明确地转换为它需要的soemthing吗?是。

第二个是这样的:

Double是否有&lt;方法?是。是否需要选项?不可以。我可以隐式地将Option转换为&lt;确实需要?否。