2012-10-04 14 views
8

Nie rozumiem pozornej sprzeczności zachowanie widzę w poniższym kodzie Scala (2.9):Scala wiele niejawnych konwersji?

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 '5.0.pluss (niektóre (5.0))' linia kompiluje, ale wiersz po nie skompilować z następującym komunikatem o błędzie:

przeciążony wartość metoda < z alternatyw: (x: Double) Boolean (x: float) Boolean (x: Long) Boolean (x: Int) Boolean (x: Char) Boolean (x: Short) Boolean (x: Byte) Boolean nie może być zastosowany do (Some [Double])

Jeśli dodać wyraźny < operatora do klasy Pimp które ma opcję [Double]:

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

Wszystko kompiluje grzywny.

Teraz droga rozumiem Scala zasady niejawna konwersja, to ma sens:

  1. Kompilator wie, że nie ma „<” operator sprawie podwójnego że akceptuje Opcja [Double]
  2. on uważa niejawna konwersja do Pimp1.
  3. Jeśli Pimp1 ma odpowiedniego operatora, działa, w przeciwnym razie generuje błąd.
  4. Co ważne, pokazuje to, że kompilator ma , a nie rozważa zastosowanie drugiej (dostępnej) niejawnej konwersji z Option [Double] na Pimp.

Tak się spodziewałem.

to jednak wydaje się być sprzeczne z pierwszego przykładu, gdzie:

  1. kompilator widzi, że nie ma pluss metoda na podwójnym.
  2. Kompilator próbuje niejawnej konwersji na Pimp, która ma taką metodę.
  3. Jednak, aby operator działał, kompilator musi zastosować drugą niejawną konwersję, aby przekonwertować ją na Pimp.

Zgodnie z powyższą logiką, nie powinno się tego kompilować, ale tak jest. Czy niejawne reguły konwersji traktują nieistniejące metody i nie pasujące metody w różny sposób?

+0

To interesujące, ponieważ po odwróceniu działa: Niektóre (5.0) <5.0 – Noah

Odpowiedz

5

To ma dla mnie sens. Pierwszy z nich działa w następujący sposób:

Czy Double ma metodę plussową? Nie, czy możemy w domyśle przekonwertować to na coś, co robi? Tak. Ok, teraz chcę zastosować metodę pluss. Czy to wymaga opcji? Nie. Czy mogę realistycznie przekonwertować opcję na cokolwiek, co się dzieje? tak.

Drugi idzie tak:

Does Pokój posiada metodę <? Tak. Czy to wymaga opcji? Nie. Czy mogę niejawnie przekonwertować opcję na coś, co zajmuje <? Nie.

+0

Prawe. Kompilator scala nie próbuje znaleźć niejawnej konwersji obiektu posiadającego już wymaganą metodę. Opcja nie ma porównania, więc niektóre (5.0) <0 działa. –

Powiązane problemy