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