简体   繁体   English

Scala多个隐式转换?

[英]Scala multiple implicit conversions?

I don't understand the apparent contradictory behavior I'm seeing in the following code (Scala 2.9): 我不理解在以下代码(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)
}

The line '5.0.pluss(Some(5.0))' compiles, but the line after it does not compile with the following error message: 可以编译“ 5.0.pluss(Some(5.0))”行,但其后的行将不会编译,并显示以下错误消息:

overloaded method value < with alternatives: (x: Double)Boolean (x: Float)Boolean (x: Long)Boolean (x: Int)Boolean (x: Char)Boolean (x: Short)Boolean (x: Byte)Boolean cannot be applied to (Some[Double]) 重载的方法值<和其他选项:(x:双精度)布尔(x:浮点数)布尔(x:长)布尔(x:整数)布尔(x:字符)布尔(x:短)布尔(x:字节)布尔适用于(Some [Double])

If I add explicit < operator to the Pimp class that takes an Option[Double]: 如果将显式<运算符添加到采用Option [Double]的Pimp类中:

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

Everything compiles fine. 一切都编译良好。

Now, the way I understand Scala implicit conversion rules, this makes perfect sense: 现在,以我理解Scala隐式转换规则的方式,这很有意义:

  1. The compiler understands that there's no '<' operator on Double that accepts Option[Double] 编译器了解Double上没有接受选项Option [Double]的'<'运算符
  2. It considers the implicit conversion to Pimp1. 它考虑了隐式转换为Pimp1。
  3. If Pimp1 has a suitable operator, it works, otherwise, it generates an error. 如果Pimp1具有合适的运算符,它将起作用,否则,它将生成错误。
  4. Importantly, this demonstrates that the compiler does not consider applying a second (available) implicit conversion, from Option[Double] to Pimp. 重要的是,这表明编译器没有考虑从Option [Double]到Pimp进行第二次(可用的)隐式转换。

This is how I expected things to work. 这就是我期望事情会发生的方式。

However, this seems to be contradicted by the first example, where: 但是,这似乎与第一个示例相矛盾,其中:

  1. The compiler sees that there's no pluss method on Double. 编译器发现Double上没有pluss方法。
  2. The compiler tries the implicit conversion to Pimp, which does have such a method. 编译器会尝试将隐式转换为Pimp,Pimp确实具有这种方法。
  3. However, in order to make the operator work, the compiler has to apply a second implicit conversion, on the argument, to convert it to Pimp. 但是,为了使运算符起作用,编译器必须对参数应用第二个隐式转换,以将其转换为Pimp。

According to the logic above, this should not compile, but it does. 根据上述逻辑,不应编译,但可以编译。 Do the implicit conversion rules treat non-existing methods and non-matching methods differently? 隐式转换规则是否对不存在的方法和不匹配的方法进行不同的处理?

This makes sense to me. 这对我来说很有意义。 The first one, that works goes like this: 第一个起作用的是这样的:

Does Double have a pluss method? Double是否有加号方法? No, can we implicitly convert it to something that does? 不,我们可以将其隐式转换为可转换的内容吗? Yes. 是。 Ok, now I want to apply the pluss method. 好的,现在我想应用pluss方法。 Does it take an Option? 需要期权吗? No. Can I implictly convert Option to soemthing that it does take? 不可以。我可以将Option隐式转换为所需的东西吗? yes. 是。

The second one goes like this: 第二个是这样的:

Does Double have a < method? Double是否有<方法? Yes. 是。 Does it take an Option? 需要期权吗? No. can I implicitly convert Option to something that < does take? 否。我可以将Option隐式转换为<确实需要的东西吗? No. 没有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM