Jak działa magia metody apply () w Scali?

79

W Scali, jeśli zdefiniuję metodę wywołaną applyw 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.

Jeff
źródło
1
Bardzo świetne wyjaśnienie, stackoverflow.com/questions/9737352/#9738862
Muhammad Hewedy,

Odpowiedzi:

67

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ęzyk f.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 .

oxbow_lakes
źródło
4
Dodałbym „kiedy fjest obiektem (łącznie z funkcjami)”. Kiedy fjest metoda, to oczywiście nie ma takiego tłumaczenia.
Alexey Romanov
2
@AlexeyRomanov: Cóż, jeśli fjest to metoda, która jest zdefiniowana bez listy parametrów, f(a)to faktycznie jest interpretowana jako coś podobnego val _tmp = f; _tmp.apply(a). Ale to naprawdę mocno wkracza w obszar rozdwajania się włosów.
Jörg W Mittag,
20

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.

sebasgo
źródło
+1 za zmianę specyfikacji języka Scala. Dodałem właściwą lokalizację, ponieważ numer Twojej strony jest nieaktualny.
Alexandre Martins
8

Pytam, ponieważ wydaje się, że Scala zdecydowanie opowiada się za konsekwentnym stosowaniem mniejszego zestawu reguł, a nie wielu reguł z wieloma wyjątkami.

Tak. I ta zasada należy do tego mniejszego zestawu.

Alexey Romanov
źródło