2012-10-04 21 views
8

No entiendo el comportamiento aparente contradicción que estoy viendo en el siguiente código (Scala 2.9):Scala ¿conversiones implícitas múltiples?

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) 
} 

El '5.0.pluss (Algunos (5.0))' línea de compilaciones, pero la línea después de no compila con el siguiente mensaje de error:

valor método sobrecargado < alternativas: (x: doble) booleano (x: Float) booleano (x: Long) booleano (x: Int) booleano (x: Char) Booleano (x: Corto) Booleano (x: Byte) Booleano no se puede aplicar a (Algunos [Doble])

Si añado explícita < operador para la clase Pimp que toma una opción [Doble]:

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

Todo compila bien.

Ahora, la forma en que entiendo las reglas de conversión implícita Scala, esto tiene mucho sentido:

  1. El compilador entiende que no hay '<' operador de doble que acepta Opción [doble]
  2. Se considera la conversión implícita a Pimp1.
  3. Si Pimp1 tiene un operador adecuado, funciona, de lo contrario, genera un error.
  4. Es importante destacar que esto demuestra que el compilador hace no considere la posibilidad de aplicar una segunda conversión implícita (disponible), desde la opción [Doble] a Pimp.

Así es como esperaba que las cosas funcionaran.

Sin embargo, esto parece estar en contradicción con el primer ejemplo, donde:

  1. El compilador ve que no hay ningún método Pluss en doble.
  2. El compilador prueba la conversión implícita a Pimp, que sí tiene dicho método.
  3. Sin embargo, para que el operador funcione, el compilador tiene que aplicar una segunda conversión implícita, en el argumento, para convertirlo a Pimp.

De acuerdo con la lógica anterior, esto no debería compilarse, pero lo hace. ¿Las reglas de conversión implícitas tratan los métodos no existentes y los métodos que no coinciden de manera diferente?

+0

Es interesante, porque si lo invierte, funciona: Algunos (5.0) <5.0 – Noah

Respuesta

5

Esto tiene sentido para mí. El primero, que funciona así:

¿El doble tiene un método de más? No, ¿podemos convertirlo implícitamente en algo que sí lo haga? Sí. Ok, ahora quiero aplicar el método plus. ¿Toma una Opción? No. ¿Puedo convertir implícitamente la opción a todo lo que toma? sí.

La segunda dice así:

cumple una doble tiene un método <? Sí. ¿Toma una Opción? No. ¿Puedo convertir implícitamente Option a algo que < toma? No.

+0

Derecha. El compilador scala no intenta encontrar una conversión implícita para un objeto que ya tiene el método requerido. La opción no tiene comparación, por lo que algunos (5.0) <0 funcionan. –

Cuestiones relacionadas