expresii switch în Dart

Forma de switch care produce o valoare: fiecare ramură este pattern => expresie.

Sintaxă
final rezultat = switch (valoare) {
  Pattern1 => expresie1,
  Pattern2 || Pattern3 => expresie2,
  _ => implicit,
};

Ce face expresii switch

Expresia switch calculează o valoare: se poate pune după =, după return, ca argument sau în corpul unei funcții =>. Fiecare ramură are forma pattern => expresie și ramurile se separă prin virgulă. Nu există case, nici default: cazul implicit se scrie _ => ....

Expresia trebuie să fie exhaustivă: orice valoare posibilă trebuie să se potrivească cu o ramură. Dacă lipsește un caz, analizorul dă eroare, ceea ce te ajută când adaugi o valoare nouă la un enum sau o subclasă nouă la o clasă sealed.

Poți folosi aceleași pattern-uri ca la instrucțiunea switch: constante, intervale, tipuri, record-uri, when.

Exemple

Exemplul 1: Valoare din intervale

Expresia switch dă direct textul calificativului.

String calificativ(int nota) => switch (nota) {
      10 => 'excepțional',
      >= 9 => 'foarte bine',
      >= 7 => 'bine',
      >= 5 => 'suficient',
      _ => 'insuficient',
    };

void main() {
  print([10, 9, 7, 5, 4].map(calificativ).toList());
}

Rezultat

[excepțional, foarte bine, bine, suficient, insuficient]

Exemplul 2: Exhaustivitate pe enum

Toate valorile enum-ului sunt tratate, deci nu e nevoie de _. O valoare nouă în Anotimp ar da eroare aici.

enum Anotimp { primavara, vara, toamna, iarna }

String activitate(Anotimp a) => switch (a) {
      Anotimp.primavara => 'plantăm flori',
      Anotimp.vara => 'mergem la mare',
      Anotimp.toamna => 'culegem struguri',
      Anotimp.iarna => 'mergem la schi la Sinaia',
    };

void main() {
  for (final a in Anotimp.values) {
    print('${a.name}: ${activitate(a)}');
  }
}

Rezultat

primavara: plantăm flori
vara: mergem la mare
toamna: culegem struguri
iarna: mergem la schi la Sinaia

Exemplul 3: Pattern-uri pe record

Se potrivește perechea (monedă, sumă); when adaugă o condiție.

String descrie((String, double) plata) => switch (plata) {
      ('RON', final suma) when suma > 1000 => 'plată mare: $suma lei',
      ('RON', final suma) => 'plată: $suma lei',
      ('EUR', final suma) => 'plată în euro: ${(suma * 4.97).toStringAsFixed(2)} lei',
      (final moneda, _) => 'monedă necunoscută: $moneda',
    };

void main() {
  print(descrie(('RON', 250)));
  print(descrie(('RON', 1500)));
  print(descrie(('EUR', 100)));
  print(descrie(('USD', 10)));
}

Rezultat

plată: 250.0 lei
plată mare: 1500.0 lei
plată în euro: 497.00 lei
monedă necunoscută: USD

Greșeli frecvente

  • Lipsa ramurii _ pe un tip cu valori nelimitate (int, String): The type 'int' is not exhaustively matched by the switch cases.
  • Folosirea lui case sau : în loc de =>: expresia are altă sintaxă decât instrucțiunea.
  • O expresie switch pusă singură la începutul unei instrucțiuni este interpretată ca instrucțiune; folosește-o într-o atribuire sau în return.

Comenzi înrudite

  • switch: Alege un bloc de cod după valoarea sau forma unei expresii; în Dart 3 fiecare case este un pattern.
  • when (guard): Adaugă o condiție suplimentară la un pattern din switch sau if-case; cazul se alege doar dacă e adevărată.
  • enum: Un tip cu un număr fix de valori numite (zilele săptămânii, stările unei comenzi), eventual cu câmpuri și metode.
  • sealed: Clasă cu un set închis de subtipuri, toate în același fișier; switch-ul pe ea verifică dacă ai tratat toate cazurile.
  • records: Grupuri de valori anonime și imutabile, de forma (a, b) sau (nume: a), ideale pentru a întoarce mai multe valori.