Sporo algorytmów jako swoje parametry przyjmuje różnego typu funkcje, które potem są wykorzystywane w trakcie ich działania. Prostym przykładem są tu wszelkiego rodzaju sortowania czy wyszukiwania, umożliwiające często podanie własnego predykatu (funkcji zwracającej wartość logiczną). W bardziej skomplikowanej wersji może chodzić chociażby o algorytm genetyczny lub przeszukujący drzewo gry, który wykorzystuje do działania jakąś funkcję oceniającą (np. osobników w populacji).
Na takie okazje różne języki programowania oferują różne narzędzia, lecz w większości przypadków sprowadzają się one do jednego z poniższych:
Niektóre języki nie mają jednak ani wskaźników, ani delegatów – w nich zwykle stosuje się sposób następny.
()
. Może więc to być zwykły wskaźnik, jakaś ładna zewnętrzna implementacja mechanizmu delegatów (np. FastDelegate) lub jakikolwiek obiekt z przeciążonym operatorem nawiasów ()
. Właśnie te ostatnie nazywa się zwykle funktorami, a jeśli ktoś nieco bardziej zagłębił się w bibliotekę STL, na pewno nie raz się z nimi spotkał.Trzeba też powiedzieć, że właściwie istnieje też inny sposób: zamiast samej funkcji przekazywanie jej… nazwy. “I niby jak ją potem wywołać?”, można zapytać. Ano to już indywidualna kwestia każdego języka – w tym przypadku zwykle interpretowanego :)
Hehe, w D jest jeszcze jedno fajne rozwiązanie:
void dotimes(int n, lazy void exp)
{
while (n–)
exp();
}
void test()
{ int x;
dotimes(3, writefln(x++));
}
W językach skryptowych chodzi nie tyle o przekazanie nazwy jako stringa, ile o to, że często w nich funkcja też jest wartością (specjalnego typu “funkcja”), którą można przekazywać.
W C# można użyć jeszcze wyrażeń lambda ;)
Mam nadzieję, że nie obrazisz się za mały offtop: grasz może dalej w WoWa?
Tak też bywa. Ale w JavaScript mamy też na przykład:
:-)