2012-10-04 13 views
8

Non capisco il comportamento apparente contraddizione che sto vedendo nel codice seguente (Scala 2.9):Scala più conversioni implicite?

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

Il '5.0.pluss (Alcuni (5.0))' linea di compilazione, ma la linea dopo essa non viene compilato con il seguente messaggio di errore:

valore metodo di overload < con alternative: (x: Double) booleano (x: Float) booleano (x: Long) booleano (x: Int) booleano (x: Char) Boolean (x: Short) Boolean (x: Byte) Boolean non può essere applicato a (Some [Double])

Se aggiungo esplicito < operatore alla classe Pimp che prende un'Opzione [Doppia]:

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

tutto compila bene.

Ora, il mio modo di capire regole di conversione implicita Scala, questo ha perfettamente senso:

  1. Il compilatore capisce che non c'è '<' operatore doppio che accetta Opzione [Doppia]
  2. considera il conversione implicita in Pimp1.
  3. Se Pimp1 ha un operatore adatto, funziona, altrimenti genera un errore.
  4. È importante notare che il compilatore fa non considera l'applicazione di una seconda conversione implicita (disponibile), da Opzione [Doppio] a Pimp.

Ecco come mi aspettavo che le cose funzionassero.

Tuttavia, questo sembra essere contraddetto dal primo esempio, dove:

  1. Il compilatore vede che non c'è nessun metodo pluss su Double.
  2. Il compilatore prova la conversione implicita in Pimp, che ha un tale metodo.
  3. Tuttavia, per far funzionare l'operatore, il compilatore deve applicare una seconda conversione implicita, sull'argomento, per convertirlo in Pimp.

Secondo la logica sopra, questo non dovrebbe essere compilato, ma lo fa. Le regole di conversione implicite trattano metodi non esistenti e metodi di non corrispondenza in modo diverso?

+0

È interessante, perché se lo si inverte, funziona: Alcuni (5.0) <5.0 – Noah

risposta

5

Questo ha senso per me. Il primo, funziona così:

Il Double ha un metodo di inclinazione? No, possiamo implicitamente convertirlo in qualcosa che fa? Sì. Ok, ora voglio applicare il metodo Pluss. Ci vuole un'opzione? No. Posso convertire implicitamente Option in tutto ciò che richiede? sì.

La seconda è questa:

fa il doppio ha un metodo <? Sì. Ci vuole un'opzione? No. Posso convertire implicitamente l'opzione in qualcosa che lo < richiede? No.

+0

A destra. Il compilatore di scala non tenta di trovare una conversione implicita per un oggetto che ha già il metodo richiesto. L'opzione non ha confronti quindi Some (5.0) <0 funziona. –

Problemi correlati