Nigdy nie zrozumiałem tego na podstawie wymyślonych rzeczowników AddTwo
odznaczania i sprawdzania ( klasa ma apply
dwa, które dodają dwa!) Przykłady.
Rozumiem, że to cukier syntaktyczny, więc (wydedukowałem z kontekstu) musiał być zaprojektowany tak, aby niektóre kody były bardziej intuicyjne.
Jakie znaczenie ma klasa z apply
funkcją? Do czego służy i do jakich celów poprawia kod (odznaczanie, sprawdzanie rzeczowników itp.)?
jak to pomaga, gdy jest używane w obiekcie towarzyszącym?
Odpowiedzi:
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 funkcjif
do jej argumentux
”.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 pobieraInt
parametr i zwraca an,Int
będzie miała typ OOFunction1[Int,Int]
.Ponieważ w Scali wszystko jest przedmiotem,
f
można je teraz traktować jako odniesienie doFunction1[Int,Int]
obiektu. Na przykład możemy wywołaćtoString
metodę odziedziczoną poAny
, która byłaby niemożliwa dla czystej funkcji, ponieważ funkcje nie mają metod:Lub możemy zdefiniować inny
Function1[Int,Int]
obiekt, wywołująccompose
metodęf
i łącząc dwie różne funkcje razem:Teraz, jeśli chcemy faktycznie wykonać funkcję lub, jak matematyk mówi „zastosuj funkcję do jej argumentów”, wywołalibyśmy
apply
metodę naFunction1[Int,Int]
obiekcie: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 jakf(args)
. Właśnie tam wkracza kompilator Scala, a gdy tylko mamy odwołanief
do obiektu funkcji i piszemy,f (args)
aby zastosować argumenty do reprezentowanej funkcji, kompilator po cichu rozwija sięf (args)
do wywołania metody obiektuf.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: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:Dlatego
apply
metoda jest po prostu wygodnym sposobem na zlikwidowanie luki między funkcjami a obiektami w Scali.źródło
class Average[YType](yZeroValue:YType)
. Jak przekazać YType ze swojego obiektu, skoro obiekty nie mogą przyjmować parametrów typu?apply
iunapply
metody do obiektu towarzyszącego klasy (między innymi). Tak definiując klasę z tylko jedną linię jak tacase class Car(make:String, model: String, year: Short, color: String)
umożliwia produkcję nowych obiektów klasy samochodów po prostu:val myCar = Car("VW","Golf",1999,"Blue")
. To jest skrót odCar.apply(...)
every object can be treated as a function, provided it has the apply method
- tyle teraz ma sens.Wynika to z faktu, że często chcesz zastosować coś do obiektu. Bardziej dokładnym przykładem jest fabryka. Gdy masz fabrykę, chcesz zastosować do niej parametr, aby utworzyć obiekt.
Scala faceci myśleli, że jak to często bywa w wielu sytuacjach, fajnie byłoby mieć skrót do połączenia
apply
. Zatem, gdy podajesz parametry bezpośrednio do obiektu, jest on wyłączany tak, jakbyś przekazał te parametry do funkcji zastosuj tego obiektu:Jest często używany w obiekcie towarzyszącym, aby zapewnić miłą fabryczną metodę dla klasy lub cechy, oto przykład:
Ze standardowej biblioteki scala możesz zobaczyć, jak
scala.collection.Seq
jest implementowany:Seq
jest cechą, dlategonew Seq(1, 2)
nie będzie się kompilował, ale dzięki obiektowi towarzyszącemu i zastosowaniu możesz wywoływać,Seq(1, 2)
a implementacja jest wybierana przez obiekt towarzyszący.źródło
Oto mały przykład dla tych, którzy chcą szybko przejrzeć
źródło