W Scali, jeśli zdefiniuję metodę wywołaną apply
w klasie lub obiekcie najwyższego poziomu, ta metoda zostanie wywołana za każdym razem, gdy dodam parę nawiasów do instancji tej klasy i umieszczę odpowiednie argumenty apply()
pomiędzy nimi. Na przykład:
class Foo(x: Int) {
def apply(y: Int) = {
x*x + y*y
}
}
val f = new Foo(3)
f(4) // returns 25
Zasadniczo object(args)
jest to po prostu cukier syntaktyczny object.apply(args)
.
Jak Scala dokonuje tej konwersji?
Czy zachodzi tutaj globalnie zdefiniowana niejawna konwersja, podobna do niejawnych konwersji typu w obiekcie Predef (ale innego rodzaju)? A może to głębsza magia? Pytam, ponieważ wydaje się, że Scala zdecydowanie opowiada się za konsekwentnym stosowaniem mniejszego zestawu reguł, a nie wielu reguł z wieloma wyjątkami. Początkowo wydaje mi się to wyjątkiem.
Odpowiedzi:
Nie sądzę, że jest coś głębiej niż dzieje się to, czego pierwotnie powiedział: to po prostu cukier syntaktyczny przy czym nawróceni kompilatora
f(a)
językf.apply(a)
jako szczególny przypadek składni.Może się to wydawać specyficzną regułą, ale tylko kilka z nich (na przykład z
update
) pozwala na konstrukcje i biblioteki podobne do DSL .źródło
f
jest obiektem (łącznie z funkcjami)”. Kiedyf
jest metoda, to oczywiście nie ma takiego tłumaczenia.f
jest to metoda, która jest zdefiniowana bez listy parametrów,f(a)
to faktycznie jest interpretowana jako coś podobnegoval _tmp = f; _tmp.apply(a)
. Ale to naprawdę mocno wkracza w obszar rozdwajania się włosów.W rzeczywistości jest na odwrót, obiekt lub klasa z metodą stosującą to normalny przypadek, a funkcja jest sposobem niejawnego konstruowania obiektu o tej samej nazwie za pomocą metody stosującej. Właściwie każda zdefiniowana funkcja jest podobiektem cechy Funkcja n (n to liczba argumentów).
Znajduje się w rozdziale 6.6: Aplikacje funkcyjne o Scala Language Specification , aby uzyskać więcej informacji na ten temat.
źródło
Tak. I ta zasada należy do tego mniejszego zestawu.
źródło