Ce face is și is!
x is String întoarce true dacă obiectul din x este un String sau un subtip al lui. is! este negația: x is! String înseamnă !(x is String).
După un if (x is String), Dart face promovare de tip (type promotion): în interiorul blocului, x este tratat ca String și poți folosi x.length fără conversii. Promovarea funcționează pentru variabile locale și parametri, nu pentru câmpuri publice (care s-ar putea schimba între verificare și folosire).
Analizorul te avertizează când verificarea este inutilă, de exemplu 5 is int, pentru că rezultatul se știe dinainte. În Dart 3, multe verificări de tip se scriu mai elegant cu pattern-uri într-un switch.
Exemple
Exemplul 1: Verificare și promovare de tip
Lista are tipul List<Object>. După fiecare is, valoarea se folosește direct ca tipul verificat.
void descrie(Object valoare) {
if (valoare is String) {
print('Text cu ${valoare.length} litere: ${valoare.toUpperCase()}');
} else if (valoare is int) {
print('Număr întreg, dublul este ${valoare * 2}');
} else if (valoare is List) {
print('Listă cu ${valoare.length} elemente');
} else {
print('Alt tip: ${valoare.runtimeType}');
}
}
void main() {
for (final v in <Object>['Iași', 21, [1, 2, 3], 3.5]) {
descrie(v);
}
}
Rezultat
Text cu 4 litere: IAȘI
Număr întreg, dublul este 42
Listă cu 3 elemente
Alt tip: double
Exemplul 2: is! pentru ieșire timpurie
Dacă valoarea nu este Map, funcția se oprește. După return, Dart știe că date este un Map.
String citesteNume(Object? date) {
if (date is! Map<String, Object?>) {
return 'date invalide';
}
final nume = date['nume'];
return nume is String ? 'Nume: $nume' : 'lipsește numele';
}
void main() {
print(citesteNume({'nume': 'Alexandra', 'oras': 'Arad'}));
print(citesteNume({'oras': 'Arad'}));
print(citesteNume('Alexandra'));
print(citesteNume(null));
}
Rezultat
Nume: Alexandra
lipsește numele
date invalide
date invalide
Exemplul 3: Subtipuri și tipuri nullable
Un int este și num, și Object. null nu este niciunul dintre ele: el are tipul Null, care intră doar în tipurile cu ?.
void verifica(Object? x) {
print('$x: num=${x is num}, int=${x is int}, double=${x is double}, Object=${x is Object}');
}
void main() {
verifica(7);
verifica(7.5);
verifica(null);
}
Rezultat
7: num=true, int=true, double=false, Object=true
7.5: num=true, int=false, double=true, Object=true
null: num=false, int=false, double=false, Object=false
Greșeli frecvente
- Să aștepți promovare pentru un câmp:
if (this.nota is int) nota + 1poate da eroare. Copiază câmpul într-o variabilă locală (final n = nota;) sau folosește un câmp privatfinal. - Verificări inutile (
'abc' is String):Unnecessary type check; the result is always 'true'. !x is Stringîn loc dex is! String: prima formă aplică!luix, nu verificării.
Comenzi înrudite
as: Spune că o valoare are un anumit tip (cast); dacă nu are, aruncă TypeError. Tot as dă un prefix unui import.Object?: Tipul de bază al tuturor valorilor din Dart, inclusiv null; varianta sigură a lui dynamic.pattern-uri (destructurare): Desfac o valoare (record, listă, map, obiect) în variabile separate, într-o singură declarație.switch: Alege un bloc de cod după valoarea sau forma unei expresii; în Dart 3 fiecare case este un pattern.dynamic: Tipul care dezactivează verificarea statică: orice metodă se poate apela, verificarea se face la rulare.