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:
- Kompilator wie, że nie ma „<” operator sprawie podwójnego że akceptuje Opcja [Double]
- on uważa niejawna konwersja do Pimp1.
- Jeśli Pimp1 ma odpowiedniego operatora, działa, w przeciwnym razie generuje błąd.
- 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:
- kompilator widzi, że nie ma pluss metoda na podwójnym.
- Kompilator próbuje niejawnej konwersji na Pimp, która ma taką metodę.
- 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?
To interesujące, ponieważ po odwróceniu działa: Niektóre (5.0) <5.0 – Noah