Ce face null safety (? ! ?? ??=)
Din Dart 2.12 (și obligatoriu din Dart 3), un tip obișnuit ca String sau int nu poate fi niciodată null. Dacă o valoare poate lipsi, adaugi ? la tip: String?. Analizorul nu te lasă să apelezi metode pe un String? până nu verifici că nu este null.
După if (x != null), variabila locală x este promovată la tipul fără ?. ?? dă o valoare de rezervă: nume ?? 'anonim'. ??= atribuie doar dacă variabila este null.
! (operatorul „null assertion”) spune „sunt sigur că nu este null”. Dacă greșești, programul aruncă o eroare la rulare. Folosește-l rar, doar când știi ceva ce analizorul nu poate deduce.
Parametri
| Parametru | Descriere |
|---|---|
Tip? |
Tipul care acceptă și null. |
x! |
Transformă T? în T; aruncă TypeError dacă x este null. |
a ?? b |
a dacă nu este null, altfel b. b se evaluează doar când e nevoie. |
a ??= b |
Atribuie b lui a doar dacă a este null. |
Exemple
Exemplul 1: Promovare după verificare
cauta poate întoarce null. După if (tel != null), tel este String și putem apela substring.
final telefoane = {'Ana': '0722111222', 'Radu': '0744333444'};
String? cauta(String nume) => telefoane[nume];
void main() {
for (final nume in ['Ana', 'Mihai']) {
final tel = cauta(nume);
if (tel != null) {
print('$nume: ${tel.substring(0, 4)}...');
} else {
print('$nume nu are telefon salvat.');
}
}
}
Rezultat
Ana: 0722...
Mihai nu are telefon salvat.
Exemplul 2: ?? și ??=
?? dă o valoare implicită; ??= completează doar câmpurile care lipsesc.
void main() {
final Map<String, String?> profil = {'nume': 'Elena', 'oras': null};
print('Oraș: ${profil['oras'] ?? 'necunoscut'}');
profil['oras'] ??= 'Brașov';
profil['nume'] ??= 'Anonim';
print(profil);
}
Rezultat
Oraș: necunoscut
{nume: Elena, oras: Brașov}
Exemplul 3: Operatorul ! și riscul lui
! pe o valoare null aruncă o eroare la rulare. Aici o prindem ca să vedem mesajul.
int? gasesteNota(Map<String, int> note, String elev) => note[elev];
void main() {
final note = {'Ana': 10, 'Dan': 8};
final notaAna = gasesteNota(note, 'Ana')!;
print('Nota Anei + 1 punct bonus: ${notaAna + 1}');
try {
final notaIon = gasesteNota(note, 'Ion')!;
print(notaIon);
} on TypeError catch (e) {
print('Eroare: $e');
}
}
Rezultat
Nota Anei + 1 punct bonus: 11
Eroare: Null check operator used on a null value
Greșeli frecvente
String nume = null;:A value of type 'Null' can't be assigned to a variable of type 'String'.!pus peste tot ca să dispară erorile: transformă fiecare loc într-o posibilă eroare la rulare. Preferă??sau o verificare.- Promovarea nu merge pe câmpuri publice:
if (this.nume != null) this.nume.lengthdă eroare. Copiază câmpul într-o variabilă locală.
Comenzi înrudite
?. și ?..: Accesul condiționat: ?. apelează o metodă doar dacă obiectul nu este null, altfel dă null.late: Amână inițializarea unei variabile nenule: valoarea se dă mai târziu sau se calculează la prima folosire.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.