Ответ 1
У математиков есть свои маленькие забавные способы, поэтому вместо того, чтобы говорить "тогда мы вызываем функцию f, передавая ее x как параметр", как мы, программисты, говорим, они говорят о "применении функции f к ее аргументу x".
В математике и информатике Применить - это функция, которая применяется функции для аргументов.
Википедия
apply служит для устранения разрыва между объектно-ориентированными и функциональными парадигмами в Scala. Каждая функция из Scala может быть представлена как объект. Каждая функция также имеет тип OO: например, функция, которая принимает параметр Int и возвращает Int, будет иметь тип OO Function1[Int,Int].
// define a function in scala
(x:Int) => x + 1
// assign an object representing the function to a variable
val f = (x:Int) => x + 1
Поскольку все объекты в Scala f теперь могут рассматриваться как ссылка на объект Function1[Int,Int]. Например, мы можем вызвать метод toString, унаследованный от Any, что было бы невозможно для чистой функции, потому что функции не имеют методов:
f.toString
Или мы могли бы определить другой объект Function1[Int,Int], вызвав метод compose на f и связав две разные функции вместе:
val f2 = f.compose((x:Int) => x - 1)
Теперь, если мы хотим фактически выполнить функцию или как математик скажем "применить функцию к своим аргументам", мы бы вызвали метод apply для объекта Function1[Int,Int]:
f2.apply(2)
Запись f.apply(args) каждый раз, когда вы хотите исполнить функцию, представленную как объект, является объектно-ориентированным способом, но добавит много шума в код без добавления дополнительной информации, и было бы неплохо иметь возможность используйте более стандартную нотацию, например f(args). Что там, где компилятор Scala входит и всякий раз, когда у нас есть ссылка f на объект функции и записывается f (args) для применения аргументов к представленной функции, компилятор молча расширяет f (args) до вызова метода объекта f.apply (args).
Каждая функция из Scala может рассматриваться как объект, и она работает и наоборот - каждый объект может рассматриваться как функция, если он имеет метод apply. Такие объекты могут использоваться в обозначении функции:
// we will be able to use this object as a function, as well as an object
object Foo {
var y = 5
def apply (x: Int) = x + y
}
Foo (1) // using Foo object in function notation
Существует много случаев использования, когда мы хотели бы рассматривать объект как функцию. Наиболее распространенным сценарием является factory pattern. Вместо добавления беспорядка в код с помощью метода factory мы можем apply object к набору аргументов для создания нового экземпляра связанного класса:
List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation
// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3)
Итак, метод apply - это просто удобный способ закрыть разрыв между функциями и объектами в Scala.