Wystarczy uzupełnić odpowiedź @chengpohi, rzeczywiście można wdrożyć dyspozytorskich statycznego (przeciążenie jest szczególnym przypadkiem) z klas typu:
trait A
trait B
implicit class RichA[Q <: A](q: Q){ def f = q }
implicit class RichB[Q <: B](q: Q){ def f = q }
scala> (new A{}).f
res0: A = [email protected]
scala> (new B{}).f
res1: B = [email protected]
Powodem dlaczego to nie działa w sposób naturalny jest tylko to, że Scala musi naśladować przeciążanie Javy (z jej usunięciem), aby zachować kompatybilność kodu z zewnętrznym kodem Java i wewnętrznymi funkcjami i gwarancjami Scala. Przeciążenie w Twoim przypadku (ale nie zawsze) jest w zasadzie statyczna wezwanie, więc może być przetwarzany w czasie kompilacji, ale JVM na invokestatic
jest dysponowanie in runtime niestety:
Przed wykonaniem invokation metody, klasy i metody zidentyfikowane przez są rozwiązane. Zobacz Rozdział 9, aby dowiedzieć się, w jaki sposób zostały rozwiązane metody.
Invokestatyczny przegląd podanego deskryptora, a określa, ile argumentów metoda przyjmuje (może to być zero). To wyrzuca te argumenty ze stosu operandów. Następnie przeszukuje listę metod statycznych zdefiniowanych przez klasę, lokalizując metodę nazwa_metody z deskryptorem deskryptora.
Tak więc, niezależnie, że wie o Q <: A
ograniczenie - nie wiedzieć o formalnym typu Q
w czasie wykonywania, więc kilka takich przypadków, że jeden wskazanym przez @chengpohi wydają się niemożliwe do wykrycia lub postanowienie (właściwie mogli to zrobić na podstawie informacji z linearyzacji - jedyną wadą jest zaangażowanie typu uruchomieniowego w wysyłanie).
Haskell, na przykład, określa właściwą metodę w czasie kompilacji (o ile wiem), więc typu zajęcia są w stanie zrekompensować braku dyspozytorski naprawdę statycznej decydując właściwą metodę zadzwonić w czasie kompilacji.
P.S. Zauważ, że w Haskell przeciążanie jest używane do dynamicznego wysyłania (dopasowywania wzorców) i klas dla statycznych, więc jest to zasadniczo odwrotnie w porównaniu do Javy.
Znalazłem ten stary post na temat tego, co wydaje się być ten sam problem. http://www.scala-lang.org/old/node/4625.html – mdm
, więc po przeczytaniu tego wątku oznacza to, że jest to "po prostu" błąd w kompilatorze Scali, który prawdopodobnie nigdy nie zostanie naprawiony; ale mam nadzieję, że działa w Dotty. Ponadto, jeśli odeślesz ten komentarz jako odpowiedź, zaakceptuję go jako poprawną odpowiedź. –