when (guard) în Dart

Adaugă o condiție suplimentară la un pattern din switch sau if-case; cazul se alege doar dacă e adevărată.

Sintaxă
case Pattern when conditie:
Pattern when conditie => expresie,
if (valoare case Pattern when conditie) { ... }

Ce face when (guard)

O „gardă” when se scrie după un pattern și conține o expresie bool. Cazul se potrivește doar dacă pattern-ul se potrivește și condiția este adevărată. În condiție poți folosi variabilele legate de pattern.

Dacă garda este falsă, Dart trece la următorul case, ca și cum pattern-ul nu s-ar fi potrivit. Funcționează în instrucțiunea switch, în expresia switch și în if-case.

Analizorul nu poate ști ce face o gardă, așa că un caz cu when nu contează la verificarea exhaustivității: ai nevoie în continuare de un caz fără gardă pentru valorile rămase.

Exemple

Exemplul 1: Reducere în funcție de vârstă

Garda compară vârsta extrasă din record.

int pretBilet((String, int) persoana) => switch (persoana) {
      (_, final varsta) when varsta < 7 => 0,
      (_, final varsta) when varsta < 18 || varsta >= 65 => 15,
      _ => 30,
    };

void main() {
  final persoane = [('Ilinca', 5), ('Tudor', 14), ('Maria', 35), ('Gheorghe', 70)];
  for (final p in persoane) {
    print('${p.$1}: ${pretBilet(p)} lei');
  }
}

Rezultat

Ilinca: 0 lei
Tudor: 15 lei
Maria: 30 lei
Gheorghe: 15 lei

Exemplul 2: Gardă în instrucțiunea switch

Ambele case-uri au același pattern, dar gărzi diferite.

void verificaParola(String parola) {
  switch (parola) {
    case String p when p.length < 8:
      print('"$p": prea scurtă');
    case String p when !p.contains(RegExp(r'[0-9]')):
      print('"$p": lipsește o cifră');
    default:
      print('"$parola": acceptată');
  }
}

void main() {
  verificaParola('mere');
  verificaParola('parolalunga');
  verificaParola('Bucuresti2024');
}

Rezultat

"mere": prea scurtă
"parolalunga": lipsește o cifră
"Bucuresti2024": acceptată

Exemplul 3: if-case cu gardă

Pattern-ul extrage temperatura; garda verifică dacă e caniculă.

void main() {
  final masuratori = [('Craiova', 38.5), ('Brașov', 24.0)];
  for (final m in masuratori) {
    if (m case (final oras, final grade) when grade >= 35) {
      print('Cod roșu de caniculă la $oras: $grade °C');
    } else {
      print('${m.$1}: temperatură normală');
    }
  }
}

Rezultat

Cod roșu de caniculă la Craiova: 38.5 °C
Brașov: temperatură normală

Greșeli frecvente

  • Să te bazezi pe un caz cu when pentru exhaustivitate: analizorul cere oricum un caz fără gardă.
  • Condiție în gardă care nu este bool: when lista.length nu compilează.
  • Gărzi cu efecte (afișări, modificări): garda se evaluează doar când pattern-ul se potrivește, deci poate rula de mai multe ori sau deloc.

Comenzi înrudite

  • switch: Alege un bloc de cod după valoarea sau forma unei expresii; în Dart 3 fiecare case este un pattern.
  • expresii switch: Forma de switch care produce o valoare: fiecare ramură este pattern => expresie.
  • if și else: Execută un bloc de cod doar dacă o condiție este adevărată; else tratează cazul contrar.
  • pattern-uri (destructurare): Desfac o valoare (record, listă, map, obiect) în variabile separate, într-o singură declarație.