2012-10-04 275 views
8

我不明白的明显矛盾的行为我看到下面的代码(斯卡拉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(一些(5.0))”编译,但行之后

重载方法值<与替代:(X:双)布尔(X:浮点型)布尔(X:长)的布尔(X:智力)布尔(X它不与下面的错误消息编译: Char)布尔值(x:Short)布尔值(x:Byte)布尔值不能应用于(某些[Double])

如果我添加明确<运营商的皮条客类,带有一个选项[双]:

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

一切编译罚款。

现在,我明白了Scala的隐式转换规则的方式,这是非常合情合理的:

  1. 编译器明白,有没有“<”双接受选项[双]
  2. 它认为运营商隐式转换为Pimp1。
  3. 如果Pimp1有一个合适的操作符,它将起作用,否则它会生成一个错误。
  4. 重要的是,这表明编译器确实而不是考虑应用从Option [Double]到Pimp的第二个(可用的)隐式转换。

这就是我期望的事情。

然而,这似乎是第一个例子,在相互矛盾:

  1. 编译器看到的是有双没有pluss方法。
  2. 编译器尝试将隐式转换为Pimp,后者确实有这种方法。
  3. 但是,为了让操作员工作,编译器必须对参数应用第二个隐式转换,将其转换为Pimp。

根据上面的逻辑,这不应该编译,但它确实。隐式转换规则是否以不同方式处理不存在的方法和非匹配方法?

+0

这很有趣,因为如果你反转它,它的工作原理:一些(5.0)<5.0 – Noah

回答

5

这对我有意义。第一个,这个作品是这样的:

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

第二个是这样的:

有双重有<方法?是。它是否需要一个选项?不,我可以隐式地将Option转换为<确实需要的东西吗?没有。

+0

正确。 scala编译器不会尝试为已经具有所需方法的对象找到隐式转换。选项没有比较,所以一些(5.0)<0的作品。 –