Ce face dynamic
O variabilă dynamic poate ține orice valoare, la fel ca Object?. Diferența: pe dynamic analizorul te lasă să apelezi orice metodă sau proprietate, fără verificare. Dacă metoda nu există, programul aruncă NoSuchMethodError abia la rulare.
Cel mai des întâlnești dynamic la date venite din afară, de exemplu JSON decodat cu jsonDecode, care dă Map<String, dynamic>. Bine este să transformi repede valorile în tipuri concrete (as String, as int).
Dacă vrei „orice valoare”, dar cu siguranță, folosește Object?: atunci trebuie să verifici tipul cu is înainte de a apela metode specifice.
Exemple
Exemplul 1: Orice valoare, orice apel
length există pe String și pe List, dar nu pe int. Eroarea apare doar la rulare.
void main() {
final List<dynamic> valori = ['Iași', [1, 2, 3], 2024];
for (final dynamic v in valori) {
try {
print('$v are lungimea ${v.length}');
} on NoSuchMethodError {
print('$v (${v.runtimeType}) nu are length');
}
}
}
Rezultat
Iași are lungimea 4
[1, 2, 3] are lungimea 3
2024 (int) nu are length
Exemplul 2: Date JSON
jsonDecode returnează dynamic. Transformăm valorile în tipuri concrete cu as.
import 'dart:convert';
void main() {
final Map<String, dynamic> elev = jsonDecode('{"nume": "Ioana", "nota": 10}');
final nume = elev['nume'] as String;
final nota = elev['nota'] as int;
print('$nume a luat nota $nota.');
}
Rezultat
Ioana a luat nota 10.
Exemplul 3: dynamic față de Object?
Cu Object? analizorul cere verificarea tipului înainte de toUpperCase(). Cu dynamic nu cere nimic.
String mare(Object? valoare) {
if (valoare is String) {
return valoare.toUpperCase();
}
return 'nu este text';
}
void main() {
dynamic d = 'brașov';
print(d.toUpperCase());
print(mare('constanța'));
print(mare(3));
}
Rezultat
BRAȘOV
CONSTANȚA
nu este text
Greșeli frecvente
- Folosirea lui
dynamicpentru că „merge oricum”: pierzi completarea automată și verificarea greșelilor de scriere. - Să confunzi
dynamiccuvar:var x = 3;are tipulint, nudynamic. - Lucrul direct pe
Map<String, dynamic>în tot programul: transformă JSON-ul într-o clasă cât mai repede.
Comenzi înrudite
Object?: Tipul de bază al tuturor valorilor din Dart, inclusiv null; varianta sigură a lui dynamic.var: Declară o variabilă care se poate modifica; tipul este dedus automat din valoarea inițială.as: Spune că o valoare are un anumit tip (cast); dacă nu are, aruncă TypeError. Tot as dă un prefix unui import.is și is!: Verifică la rulare dacă o valoare are un anumit tip; după verificare, variabila poate fi folosită ca acel tip.