Как работает волшебство метода apply() в Scala?
В Scala, если я определю метод с именем apply
в классе или объекте верхнего уровня этот метод будет вызываться всякий раз, когда я добавляю пару скобок к экземпляру этого класса и помещаю соответствующие аргументы для apply()
между ними. Например:
class Foo(x: Int) {
def apply(y: Int) = {
x*x + y*y
}
}
val f = new Foo(3)
f(4) // returns 25
В общем, object(args)
это просто синтаксический сахар для object.apply(args)
,
Как Scala делает это преобразование?
Существует ли здесь глобально определенное неявное преобразование, подобное неявным преобразованиям типов в объекте Predef (но различное по своему характеру)? Или это какая-то более глубокая магия? Я спрашиваю, потому что кажется, что Scala решительно выступает за последовательное применение меньшего набора правил, а не многих правил со многими исключениями. Это поначалу кажется мне исключением.
3 ответа
Я не думаю, что происходит что-то более глубокое, чем то, что вы изначально сказали: это просто синтаксический сахар, посредством которого компилятор преобразует f(a)
в f.apply(a)
как особый случай синтаксиса.
Это может показаться конкретным правилом, но только некоторые из них (например, с update
) допускает DSL- подобные конструкции и библиотеки.
На самом деле все наоборот: объект или класс с методом apply является нормальным случаем, а функция является способом неявного создания объекта с тем же именем с помощью метода apply. Фактически каждая функция, которую вы определяете, является подобъектом признака Functionn (n - количество аргументов).
Обратитесь к разделу 6.6: Приложения функций на странице 77 Спецификации языка Scala для получения дополнительной информации по этой теме.
Я спрашиваю, потому что кажется, что Scala решительно выступает за последовательное применение меньшего набора правил, а не многих правил со многими исключениями.
Да. И это правило относится к этому меньшему набору.