funcții anonime în Dart

Funcții Dart 1.0

Funcții fără nume, scrise direct unde sunt folosite (lambda, closure); își amintesc variabilele din jur.

Sintaxă
(parametri) { ... }
(parametri) => expresie
final f = (int x) => x * 2;

Ce face funcții anonime

O funcție anonimă (lambda) se scrie ca o funcție obișnuită, dar fără tip returnat și fără nume: (x) => x * 2 sau (x) { return x * 2; }. Se folosește mai ales ca argument pentru map, where, sort, forEach sau la evenimente.

Tipurile parametrilor se deduc de obicei din context: în lista.map((x) => ...), Dart știe că x are tipul elementelor listei.

O funcție anonimă este un closure: își amintește variabilele din locul unde a fost creată și le poate modifica, chiar și după ce funcția exterioară s-a terminat.

Exemple

Exemplul 1: Ca argument pentru metodele listelor

where, map și sort primesc funcții anonime.

void main() {
  final elevi = [('Ana', 9.5), ('Bogdan', 6.8), ('Cristina', 8.2), ('Dan', 4.9)];

  final promovati = elevi.where((e) => e.$2 >= 5).toList();
  promovati.sort((a, b) => b.$2.compareTo(a.$2));
  print(promovati.map((e) => '${e.$1} (${e.$2})').join(', '));
}

Rezultat

Ana (9.5), Cristina (8.2), Bogdan (6.8)

Exemplul 2: Closure care ține minte o stare

Funcția întoarsă de contor își păstrează propriul numar între apeluri.

int Function() contor(String nume) {
  var numar = 0;
  return () {
    numar++;
    print('$nume: $numar');
    return numar;
  };
}

void main() {
  final vizite = contor('vizite');
  final clicuri = contor('clicuri');
  vizite();
  vizite();
  clicuri();
  vizite();
}

Rezultat

vizite: 1
vizite: 2
clicuri: 1
vizite: 3

Exemplul 3: Funcție anonimă cu mai multe rânduri

Corpul cu acolade permite mai multe instrucțiuni.

void main() {
  final cos = {'Cafea': 24.0, 'Zahăr': 5.5, 'Lapte': 7.25};
  var total = 0.0;
  cos.forEach((produs, pret) {
    total += pret;
    print('${produs.padRight(6)} ${pret.toStringAsFixed(2)} lei');
  });
  print('Total  ${total.toStringAsFixed(2)} lei');
}

Rezultat

Cafea  24.00 lei
Zahăr  5.50 lei
Lapte  7.25 lei
Total  36.75 lei

Greșeli frecvente

  • (x) => { 'a': x } înseamnă Map, dar (x) => {x} înseamnă Set: dacă voiai un bloc, scrie (x) { ... } fără =>.
  • Funcții anonime lungi, imbricate: dă-le un nume (funcție locală) ca să se citească ușor.
  • return într-o funcție anonimă din forEach nu oprește parcurgerea, ci doar apelul curent.

Comenzi înrudite

  • funcții: Blocuri de cod cu nume, care primesc parametri și returnează o valoare; în Dart sunt și obiecte.
  • funcții săgeată (=>): Forma scurtă a unei funcții: => expresie înseamnă { return expresie; }.
  • typedef: Dă un nume (alias) unui tip, de obicei unui tip de funcție sau unui tip generic lung.