dynamic în Dart

Tipul care dezactivează verificarea statică: orice metodă se poate apela, verificarea se face la rulare.

Sintaxă
dynamic x = valoare;
List<dynamic> lista;
Map<String, dynamic> json;

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 dynamic pentru că „merge oricum”: pierzi completarea automată și verificarea greșelilor de scriere.
  • Să confunzi dynamic cu var: var x = 3; are tipul int, nu dynamic.
  • 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.