Expando în Dart

Atașează valori suplimentare unor obiecte existente, fără să le modifici clasa și fără să le ții în viață.

Sintaxă
Expando<T extends Object>([String? name])
T? operator [](Object object)
void operator []=(Object object, T? value)

Ce face Expando

Un Expando funcționează ca un Map în care cheile sunt obiecte: info[obiect] = valoare și info[obiect]. Diferența importantă este că păstrează cheile slab: dacă obiectul nu mai este folosit nicăieri altundeva, poate fi șters din memorie, iar valoarea lui dispare odată cu el. Un Map obișnuit l-ar ține în viață pentru totdeauna.

Este util când vrei să adaugi informații la obiecte din clase pe care nu le poți modifica (din alte biblioteci), de exemplu un cache sau un id intern. Valoarea pentru un obiect fără intrare este null; setarea la null șterge intrarea.

Cheile se compară după identitate, nu cu ==. Nu pot fi chei numerele, textele, valorile bool, null sau record-urile.

Parametri

Parametru Descriere
name Un nume opțional, folosit doar la depanare.
object Obiectul căruia i se atașează valoarea.

Ce returnează

[]: valoarea atașată sau null.

Exemple

Exemplul 1: Informații atașate unor obiecte

class Fisier {
  final String cale;
  Fisier(this.cale);
}

final numarCitiri = Expando<int>('citiri');

String citeste(Fisier f) {
  numarCitiri[f] = (numarCitiri[f] ?? 0) + 1;
  return 'conținutul lui ${f.cale}';
}

void main() {
  var a = Fisier('note.txt');
  var b = Fisier('orar.txt');
  citeste(a);
  citeste(a);
  citeste(b);
  print('${a.cale}: citiri = ${numarCitiri[a]}');
  print('${b.cale}: citiri = ${numarCitiri[b]}');
  print(numarCitiri[Fisier('note.txt')]);
  numarCitiri[b] = null;
  print(numarCitiri[b]);
}

Rezultat

note.txt: citiri = 2
orar.txt: citiri = 1
null
null

Exemplul 2: Chei nepermise

void main() {
  var e = Expando<String>();
  try {
    e['Iași'] = 'oraș';
  } on ArgumentError catch (err) {
    print('Text ca cheie: ${err.message}');
  }
  var lista = [1, 2];
  e[lista] = 'listă';
  print(e[lista]);
  print(e[[1, 2]]);
}

Rezultat

Text ca cheie: Cannot be a string, number, boolean, record, null, Pointer, Struct or Union
listă
null

Greșeli frecvente

  • Folosești texte sau numere ca chei: aruncă ArgumentError. Pentru ele folosește un Map.
  • Te aștepți ca două obiecte egale să aibă aceeași valoare. Expando compară după identitate.

Comenzi înrudite

  • WeakReference: O referință care nu ține obiectul în viață; target dă obiectul sau null după ce a fost șters din memorie.
  • identical: Verifică dacă două variabile arată spre exact același obiect din memorie, nu doar spre obiecte egale.
  • Map: Colecție de perechi cheie–valoare: cauți rapid o valoare după cheia ei (nume, cod, oraș).