enum în Dart

Tipuri, generics, records și pattern-uri Dart 1.8 (enum-uri cu câmpuri și metode din Dart 2.17)

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.

Sintaxă
enum Nume { valoare1, valoare2, valoare3 }

enum Nume {
  a(1), b(2);                 // valori cu argumente
  final int camp;
  const Nume(this.camp);
  Tip metoda() => ...;
}

Nume.values, Nume.a.name, Nume.a.index

Ce face enum

Un enum (enumerare) definește un tip care poate avea doar valorile enumerate: enum Anotimp { primavara, vara, toamna, iarna }. O variabilă de tip Anotimp nu poate primi altceva, iar un switch pe ea este verificat pentru exhaustivitate.

Fiecare valoare are name (numele ca text, 'vara') și index (poziția, de la 0). Lista tuturor valorilor este Anotimp.values, iar Anotimp.values.byName('vara') găsește o valoare după nume.

Din Dart 2.17, enum-urile pot avea câmpuri final, un constructor const, metode și getter-e și pot implementa interfețe. Valorile se scriu primele, urmate de ;.

Exemple

Exemplul 1: Enum simplu și switch

Expresia switch tratează toate cele patru valori, fără default.

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 => 'ne dăm cu sania',
    };

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

Rezultat

0. primavara: plantăm flori
1. vara: mergem la mare
2. toamna: culegem struguri
3. iarna: ne dăm cu sania
Anotimp.vara

Exemplul 2: Enum cu câmpuri și metode

Fiecare monedă are simbolul și cursul față de leu; metoda inLei face conversia.

enum Moneda {
  ron('lei', 1),
  eur('€', 4.97),
  usd('\$', 4.58);

  final String simbol;
  final double cursLei;
  const Moneda(this.simbol, this.cursLei);

  double inLei(double suma) => suma * cursLei;
  bool get esteLocala => this == Moneda.ron;
}

void main() {
  for (final m in Moneda.values) {
    print('${m.name}: 100 ${m.simbol} = ${m.inLei(100).toStringAsFixed(2)} lei, locală: ${m.esteLocala}');
  }
}

Rezultat

ron: 100 lei = 100.00 lei, locală: true
eur: 100 € = 497.00 lei, locală: false
usd: 100 $ = 458.00 lei, locală: false

Exemplul 3: Enum care implementează Comparable

Prioritățile se pot sorta după nivel, nu după ordinea scrierii.

enum Prioritate implements Comparable<Prioritate> {
  scazuta(1),
  urgenta(3),
  normala(2);

  final int nivel;
  const Prioritate(this.nivel);

  @override
  int compareTo(Prioritate alta) => nivel - alta.nivel;
}

void main() {
  final sarcini = {'Factura Enel': Prioritate.urgenta, 'Curățenie': Prioritate.scazuta, 'Raport': Prioritate.normala};
  final ordonate = sarcini.entries.toList()..sort((a, b) => b.value.compareTo(a.value));
  for (final s in ordonate) {
    print('${s.value.name.padRight(8)} ${s.key}');
  }
}

Rezultat

urgenta  Factura Enel
normala  Raport
scazuta  Curățenie

Greșeli frecvente

  • Să compari a.name == 'vara' în loc de a == Anotimp.vara: textul nu este verificat de analizor, valoarea da.
  • Să te bazezi pe index când salvezi datele: dacă reordonezi valorile, indicii se schimbă. Salvează name.
  • Anotimp.values.byName('Vara') cu alt text decât numele exact: aruncă ArgumentError.

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.
  • sealed: Clasă cu un set închis de subtipuri, toate în același fișier; switch-ul pe ea verifică dacă ai tratat toate cazurile.
  • const: Declară o constantă calculată la compilare; obiectele const sunt complet imuabile și partajate.