Ce face ?. și ?..
a?.b înseamnă: dacă a este null, rezultatul este null și b nu se mai evaluează; altfel este a.b. Așa poți merge pe un lanț de obiecte care pot lipsi fără să scrii multe if-uri: elev?.adresa?.oras. Rezultatul este mereu de tip nullabil.
Varianta pentru index este lista?[0]. Varianta pentru cascadă, ?.., execută toată cascada doar dacă obiectul nu este null: buffer?..write('a')..write('b').
Se combină des cu ??: elev?.adresa?.oras ?? 'necunoscut'. Dacă obiectul nu poate fi null, analizorul semnalează ?. ca inutil.
Exemple
Exemplul 1: Lanț de câmpuri care pot lipsi
Al doilea elev nu are adresă, deci ?. oprește lanțul și dă null; ?? pune textul implicit.
class Adresa {
final String oras;
Adresa(this.oras);
}
class Elev {
final String nume;
final Adresa? adresa;
Elev(this.nume, [this.adresa]);
}
void main() {
final elevi = [Elev('Ana', Adresa('Iași')), Elev('Mihai')];
for (final e in elevi) {
final oras = e.adresa?.oras;
print('${e.nume}: ${oras ?? 'adresă necunoscută'} (lungime: ${oras?.length})');
}
}
Rezultat
Ana: Iași (lungime: 4)
Mihai: adresă necunoscută (lungime: null)
Exemplul 2: Index condiționat ?[]
note?[0] citește primul element doar dacă lista există.
List<int>? noteleLui(String elev) => elev == 'Ana' ? [10, 9] : null;
void main() {
for (final elev in ['Ana', 'Dan']) {
final prima = noteleLui(elev)?[0];
print('$elev: prima notă = ${prima ?? '-'}');
}
}
Rezultat
Ana: prima notă = 10
Dan: prima notă = -
Exemplul 3: Cascadă condiționată ?..
Cascada se aplică doar pe bufferul care există; pentru null nu se întâmplă nimic.
StringBuffer? creeaza(bool activ) => activ ? StringBuffer() : null;
void main() {
for (final activ in [true, false]) {
final sb = creeaza(activ)
?..write('Comandă: ')
..write('3 caiete');
print(sb?.toString() ?? 'fără buffer');
}
}
Rezultat
Comandă: 3 caiete
fără buffer
Greșeli frecvente
?.pe un obiect care nu poate finull: avertismentulThe receiver can't be null, so the null-aware operator '?.' is unnecessary.- Să uiți că rezultatul lui
?.este nullabil:int n = text?.length;nu compilează; adaugă?? 0. ?..doar la prima operație: restul cascadei se scrie cu..simplu, toată cascada este sărită când obiectul enull.
Comenzi înrudite
null safety (? ! ?? ??=): Tipurile nu pot fi null decât dacă au ?; operatorii !, ?? și ??= lucrează cu valorile care pot lipsi.cascade (..): Operatorul .. face mai multe operații pe același obiect, una după alta, fără să repeți numele lui.Object?: Tipul de bază al tuturor valorilor din Dart, inclusiv null; varianta sigură a lui dynamic.