Ответ 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.