witam,
czy mógłby ktoś wytlumaczyc mi zastosowanie funkcji anonimowych na przykładzie. Z góry dziękuję.
Nie wiem jak wyglada to w Pascalu ale w wiekszosci przypadkow bedziesz mial cos pokroju
Range(from = 0, to = 1337).filter(i => i % 2 == 0) // Seq(0, 2, 4, 6, 8, 10, 12, ..., 1336)
images.map(img => new ImageView(img))
Generalnie funkcja bedzie przyjmowac funkcje i bedziesz te funkcje (anonimowa) opisywac w miejscu uzycia.
W opozycji do np. C gdzie musialbys zrobic funkcje nazwana:
static bool is_even(int i) {
return i % 2 == 0;
}
... {
filter(initialRange, n, filteredRange, &is_even);
}
Ogólnie rozumiem funkcje anonimowe ale nie udało mi się rozgryźć jak są przekazywane parametry do funkcji anonimowej jeśli sama funkcja użyta jest jako parametr w innej funkcji zwykłej.
neytro napisał(a):
Ogólnie rozumiem funkcje anonimowe ale nie udało mi się rozgryźć jak są przekazywane parametry do funkcji anonimowej jeśli sama funkcja użyta jest jako parametr w innej funkcji zwykłej.
Nie rozumiem, mozesz podac przyklad?
Ale po pierwsze to funkcja anonimowa dalej moze przyjmowac argumenty a po drugie ona zyje razem ze swoim domknieciem
https://en.wikipedia.org/wiki/Closure_(computer_programming)
Tak samo jak w każdym innym języku czyli mogę lepiej/łatwiej/inaczej wykorzystać możliwość przekazywania funkcji jako parametru bez konieczności tworzenia jej deklaracji.
Przykład:
{$apptype console}
program anon;
uses
Windows,
SysUtils;
type
TMyData = array[ 0 .. 1000 ] of byte ;
TMyCalcFunction = reference to function ( dataItem : byte ) : byte ;
function processData ( var data : TMyData; calcFunction : TMyCalcFunction ) : boolean ;
var i: Integer;
begin
for i := 0 to 1000 do
begin
data [ i ] := calcFunction ( data [ i ] ) ;
end;
end;
var someMyData : TMyData ;
begin
// Tu wypełniam tabl;icę pustymi danymi...
processData ( someMyData, function ( x : byte ) : byte begin
result := 0 ;
end );
writeln ( 'Item id = 10: ', someMyData [ 10 ] );
// A tu sobie coś zmieniam...
processData ( someMyData, function ( x : byte ) : byte begin
result := x + 1 ;
end );
writeln ( 'Item id = 10: ', someMyData [ 10 ] );
readln;
end.
Może inaczej jak sa przekazywane parametry funkcji anonimowej. w Funkcji zwykłej robimy to tak np. copy('zdani3', 10,4)
@neytro: Jak w przykładzie nad Twoim postem.
Do tego możesz zrobić także tak:
type
TSimpleProcedure = reference to procedure;
TSimpleFunction = reference to function(x: string): Integer;
var
x1: TSimpleProcedure;
y1: TSimpleFunction;
begin
x1 := procedure
begin
Writeln('Hello World');
end;
x1; //invoke anonymous method just defined
y1 := function(x: string): Integer
begin
Result := Length(x);
end;
Writeln(y1('bar'));
end.
jak są przekazywane parametry do funkcji anonimowej jeśli sama funkcja użyta jest jako parametr w innej funkcji zwykłej
def filter(predicate: T => Boolean): List[T] = {
val result = mutable.ListBuffer.empty[T]
for (item <- this.items) {
if (predicate(item)) result.add(item)
}
result.toList
}
List(1,2,3,4,5,6,7,8,9).filter(i => i % 2 == 0 && i > 5) // List(6, 8)
Ponownie sorry, ze inny jezyk ale zasada ta sama :P
Dziękuję za wasze odpowiedzi teraz wszystko jasne :)
neytro napisał(a):
Może inaczej jak sa przekazywane parametry funkcji anonimowej. w Funkcji zwykłej robimy to tak np. copy('zdani3', 10,4)
Metoda anonimowa różni się od zwykłej jedynie tym, że nie posiada swojej nazwy (bo ma być anonimowa) i jest zadeklarowana wewnątrz bloku kodu innej metody (albo zwykłej procedury czy funkcji). Taka metoda może być przypisana do zmiennej konkretnego typu funkcyjnego (jeśli ma zwracać wynik) lub proceduralnego (jeśli wyniku nie zwraca) — to pokazał @katakrowa, jak zadeklarować i przypisać funkcję do zmiennej.
Można też wywołać metodę anonimową w miejscu, w którym normalnie podaje się parametr — tutaj zmiennej nie potrzeba, a przykładem są np. metody sortujące, pobierające w parametrze funkcję porównywania elementów listy. Przykład:
type
TIntegerComparer = TComparer;
{..}
var
List : TList;
Item : integer;
begin
List := TList.Create();
try
List.Add(2);
List.Add(4);
List.Add(3);
List.Add(4);
List.Add(5);
List.Add(1);
for Item in List do ShowMessage(IntToStr(Item)); // 2, 4, 3, 4, 5, 1
// sortowanie z użyciem metody anonimowej
List.Sort(TIntegerComparer.Construct(
function(const L, R: Integer): Integer
begin
Result := R - L;
end
)
);
for Item in List do ShowMessage(IntToStr(Item)); // 5, 4, 4, 3, 2, 1
finally
List.Free();
end;
end;