У математиків є свої маленькі кумедні способи, тому замість того, щоб говорити "тоді ми називаємо функцію, 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
Є багато випадків використання, коли ми хотіли б розглядати об'єкт як функцію. Найпоширеніший сценарій - це заводський зразок . Замість того, щоб додавати безлад до коду фабричним методом, ми можемо apply
заперечити набір аргументів для створення нового примірника асоційованого класу:
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.