В 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 настоятельно поддерживает последовательное применение меньшего набора правил, а не многих правил с множеством исключений. Сначала это кажется мне исключением.
Ответы:
Я не думаю, что происходит что-то более глубокое, чем то, что вы изначально сказали: это просто синтаксический сахар, посредством которого компилятор преобразуется
f(a)
вf.apply(a)
специальный синтаксический случай.Это может показаться особым правилом, но лишь некоторые из них (например, с
update
) допускают использование DSL- подобных конструкций и библиотек.источник
f
это объект (включая функции)». Когдаf
есть метод, такого перевода явно нет.f
это метод, который определен без списка параметров, тоf(a)
действительно интерпретируется как что-то вродеval _tmp = f; _tmp.apply(a)
. Но это действительно твердо входит в область «секущихся волос».На самом деле все наоборот: объект или класс с методом apply - это нормальный случай, а функция - это способ неявно конструировать объект с тем же именем с помощью метода apply. Фактически каждая определяемая вами функция является подобъектом признака Function n (n - количество аргументов).
Обратитесь к разделу 6.6: Функция Приложение о спецификации Scala языка для получения дополнительной информации о теме.
источник
Да. И это правило принадлежит к этому меньшему набору.
источник