Matematycy mają swoje własne zabawne sposoby, więc zamiast mówić „wtedy funkcję nazywamy f
przekazując ją x
jako parametr”, jak powiedzieliby to programiści, mówią o „zastosowaniu funkcji f
do jej argumentu x
”.
W matematyce i informatyce Apply to funkcja, która stosuje funkcje do argumentów.
Wikipedia
apply
służy do zlikwidowania luki między paradygmatami obiektowymi i funkcjonalnymi w Scali. Każda funkcja w Scali może być reprezentowana jako obiekt. Każda funkcja ma również typ OO: na przykład funkcja, która pobiera Int
parametr i zwraca an, Int
będzie miała typ 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
Ponieważ w Scali wszystko jest przedmiotem, f
można je teraz traktować jako odniesienie do Function1[Int,Int]
obiektu. Na przykład możemy wywołać toString
metodę odziedziczoną po Any
, która byłaby niemożliwa dla czystej funkcji, ponieważ funkcje nie mają metod:
f.toString
Lub możemy zdefiniować inny Function1[Int,Int]
obiekt, wywołując compose
metodę f
i łącząc dwie różne funkcje razem:
val f2 = f.compose((x:Int) => x - 1)
Teraz, jeśli chcemy faktycznie wykonać funkcję lub, jak matematyk mówi „zastosuj funkcję do jej argumentów”, wywołalibyśmy apply
metodę na Function1[Int,Int]
obiekcie:
f2.apply(2)
Pisanie za f.apply(args)
każdym razem, gdy chcesz wykonać funkcję reprezentowaną jako obiekt, jest zorientowane obiektowo, ale dodałoby dużo bałaganu do kodu bez dodawania wielu dodatkowych informacji i byłoby fajnie móc użyć bardziej standardowej notacji, takiej jak jak f(args)
. Właśnie tam wkracza kompilator Scala, a gdy tylko mamy odwołanie f
do obiektu funkcji i piszemy, f (args)
aby zastosować argumenty do reprezentowanej funkcji, kompilator po cichu rozwija się f (args)
do wywołania metody obiektu f.apply (args)
.
Każda funkcja w Scali może być traktowana jako obiekt i działa również w drugą stronę - każdy obiekt może być traktowany jako funkcja, pod warunkiem, że ma taką apply
metodę. Takie obiekty mogą być używane w notacji funkcji:
// 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
Istnieje wiele przypadków użycia, w których chcielibyśmy traktować obiekt jako funkcję. Najczęstszym scenariuszem jest wzór fabryczny . Zamiast dodawać bałaganu do kodu za pomocą metody fabrycznej, możemy apply
sprzeciwić się zestawowi argumentów, aby utworzyć nową instancję powiązanej klasy:
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)
Dlatego apply
metoda jest po prostu wygodnym sposobem na zlikwidowanie luki między funkcjami a obiektami w Scali.