2009-08-03 16 views
76

W Scali, jeśli zdefiniuję metodę o nazwie apply w klasie lub obiekcie najwyższego poziomu, ta metoda zostanie wywołana za każdym razem, gdy dodaję parę nawiasów do instancji tej klasy, i wstawię odpowiednie argumenty dla apply() pomiędzy im. Na przykład:W jaki sposób działa magiczna metoda Scali()?

class Foo(x: Int) { 
    def apply(y: Int) = { 
     x*x + y*y 
    } 
} 

val f = new Foo(3) 
f(4) // returns 25 

Więc zasadniczo object(args) jest po prostu cukier syntaktyczny dla object.apply(args).

W jaki sposób Scala wykonuje tę konwersję?

Czy jest tutaj globalnie zdefiniowana niejawna konwersja, podobna do niejawnych konwersji typów w obiekcie Predef (ale innego rodzaju)? A może jest to trochę głębsza magia? Pytam, ponieważ wygląda na to, że Scala zdecydowanie preferuje konsekwentne stosowanie mniejszego zbioru reguł, a nie wiele reguł z wieloma wyjątkami. To początkowo wydaje mi się wyjątkiem.

+1

Bardzo dobre wyjaśnienie, http://stackoverflow.com/questions/9737352/#9738862 –

Odpowiedz

62

Nie sądzę, że jest coś głębszego niż to, co pierwotnie powiedziałeś: to tylko cukier syntaktyczny, w którym kompilator konwertuje f(a) na f.apply(a) jako specjalną wielkość składni.

Może to wydawać się określoną regułą, ale tylko kilka z nich (na przykład z update) pozwala na konstrukcje i biblioteki podobne do DSL.

+0

Jeśli zamienisz f (a) i f.apply (a), to jest poprawne;) – sebasgo

+2

Myślę, że miałem rację za pierwszym razem ;-P –

+4

Dodałbym "kiedy' f' jest obiektem (włączając funkcje) " . Kiedy 'f' jest metodą, oczywiście nie ma takiego tłumaczenia. –

19

W rzeczywistości jest odwrotnie, obiekt lub klasa z metodą stosowaną jest normalnym przypadkiem, a funkcja jest sposobem konstruowania niejawnie obiektu o tej samej nazwie z metodą stosowaną. W rzeczywistości każda zdefiniowana funkcja jest podobiektem cechy (n jest liczbą argumentów).

Patrz sekcja 6.6: Zastosowanie funkcji na stronie 77 instrukcji Scala Language Specification, aby uzyskać więcej informacji na dany temat.

+0

+1 za zmianę specyfikacji językowej Scala. Dodałem odpowiednią lokalizację, ponieważ numer Twojej strony jest nieaktualny. –

7

Pytam, ponieważ wygląda na to, że Scala zdecydowanie faworyzuje konsekwentne stosowanie mniejszego zbioru reguł, a nie wielu reguł z wieloma wyjątkami.

Tak. I ta reguła należy do tego mniejszego zestawu.

Powiązane problemy