Nullable e non nullable
Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 24 di 110.
Ora che hai capito perché la sicurezza rispetto ai valori null è importante, vediamo come dichiarare variabili che possono contenere null. In Dart, rendi nullable un tipo aggiungendo un ? dopo il nome del tipo.
String name = 'Alice'; // Non nullable - deve sempre avere un valore
String? nickname; // Nullable - può essere null o una String
print(name); // Alice
print(nickname); // nullLa differenza fondamentale è che i tipi non nullable garantiscono l'esistenza di un valore, mentre i tipi nullable consentono esplicitamente l'assenza di un valore. Questa distinzione si applica a tutti i tipi:
int count = 10; // Deve avere un valore
int? optionalCount; // Può essere null
List<String> items = []; // Deve essere una lista (può essere vuota)
List<String>? maybeItems; // Potrebbe essere null (nessuna lista)Nota che una lista vuota [] è diversa da null. Una lista vuota esiste, ma non contiene nulla; null significa che non esiste alcuna lista.
Il compilatore applica rigorosamente queste regole. Non puoi assegnare null a una variabile non nullable e non puoi usare una variabile nullable dove è prevista una non nullable senza prima verificare che sia null:
String? maybeName = 'Bob';
// String definite = maybeName; // Errore! Non è possibile assegnare un valore nullable a uno non-nullableNella prossima lezione imparerai gli operatori che Dart mette a disposizione per lavorare in sicurezza con i valori nullable.
Sfida
FacileCreiamo un sistema di lista di film da vedere che dimostra la differenza tra informazioni obbligatorie e facoltative usando tipi nullable e non-nullable.
Creerai due file per organizzare il codice:
movie.dart: Definisci una classeMovieche rappresenta un film nella tua lista. Ogni film deve avere un titolo e l'anno di uscita (sono sempre obbligatori), ma alcuni dettagli aggiuntivi potrebbero non essere disponibili per tutti i film. La tua classe dovrebbe avere:- Una
String titlenon-nullable: ogni film deve avere un titolo - Un
int yearnon-nullable: ogni film deve avere un anno di uscita - Una
String? directornullable: il regista potrebbe essere sconosciuto - Un
double? ratingnullable: non tutti i film hanno già ricevuto una valutazione - Un costruttore che accetta
titleeyearcome parametri obbligatori - Un metodo
displayInfo()che stampa le informazioni sul film, mostrandoUnknownse il regista non è disponibile eNot ratedse manca la valutazione
- Una
main.dart: Importa la classe dei film e crea una piccola lista che mostri dati dei film sia completi sia incompleti:- Crea un film con il titolo
'Inception'e l'anno2010, poi imposta il regista su'Christopher Nolan'e la valutazione su8.8 - Crea un film con il titolo
'The Matrix'e l'anno1999, poi imposta solo la valutazione su8.7(lascia il regista impostato su null) - Crea un film con il titolo
'Upcoming Film'e l'anno2025(lascia sia il regista sia la valutazione impostati su null) - Chiama
displayInfo()su ciascun film nell'ordine indicato sopra
- Crea un film con il titolo
Il metodo displayInfo() dovrebbe stampare nel seguente formato esatto:
[title] ([year])
Director: [director or "Unknown"]
Rating: [rating or "Not rated"]Nota che i campi non-nullable (title e year) hanno sempre un valore garantito, mentre i campi nullable (director? e rating?) possono rimanere non impostati. Questo riflette situazioni del mondo reale in cui alcuni dati sono essenziali e altri facoltativi.
Risultato previsto:
Inception (2010)
Director: Christopher Nolan
Rating: 8.8
The Matrix (1999)
Director: Unknown
Rating: 8.7
Upcoming Film (2025)
Director: Unknown
Rating: Not ratedProvalo tu
import 'movie.dart';
void main() {
// TODO: Crea un film con titolo 'Inception' e anno 2010
// Poi imposta director su 'Christopher Nolan' e rating su 8.8
// TODO: Crea un film con titolo 'The Matrix' e anno 1999
// Poi imposta solo rating su 8.7 (lascia director a null)
// TODO: Crea un film con titolo 'Upcoming Film' e anno 2025
// Lascia sia director sia rating a null
// TODO: Chiama displayInfo() su ogni film nell'ordine indicato
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniLibrerie e importazioniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave thisMetodiVariabili di istanzaFondamenti dei costruttoriRiepilogo - Calcolatrice semplice4Sicurezza dei valori null
Introduzione alla sicurezza dei valori nullNullable e non nullableGli operatori ? e !La keyword late e la sicurezza dei valori nullOperatori null-awareSicurezza dei valori null nelle classiRiepilogo - Sistema di profili utente7Classi astratte e interfacce
Classi astratteMetodi astrattiInterfacce in DartInterfacce impliciteImplementare vs estendereInterfacce multipleRiepilogo - Calcolatore di forme10Collezioni e generici
Panoramica di List, Set e MapCollezioni sicure rispetto ai tipiClassi genericheMetodi genericiVincoli sui genericiIterable e IteratorRiepilogo - Archiviazione generica13Concetti avanzati di OOP
Composizione vs ereditarietàMetodi di estensioneClassi chiamabiliClassi sealed (Dart 3)Record (Dart 3)Pattern e matching (3.0)Enum con metodi16Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente2I costruttori in Dart
Costruttore predefinitoCostruttori con nomeListe di inizializzazioneCostruttori costantiCostruttori factoryCostruttori di reindirizzamentoRiepilogo - Crea forme5Incapsulamento
Membri pubblici e privatiConvenzione del prefisso _Visibilità a livello di libreriaApprofondimento su getter e setterNascondimento delle informazioniRiepilogo - Registri degli studenti8Mixin
Introduzione ai MixinCreare MixinUsare più MixinParola chiave on nei MixinMixin vs ereditarietàMixin vs interfacciaRiepilogo - Sistema animale11Metodi speciali
Sovrascrittura di toString()Sovrascrittura di hashCode e ==Interfaccia ComparableMetodo call()Sovrascrittura di noSuchMethodRiepilogo - Collezione personalizzata14Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneSingletonFactoryObserverStrategy3Proprietà delle classi
Membri di istanza e staticiCampi final e constVariabili lateMetodi e campi staticiGetter e setterRiepilogo - Gestore di conti bancari6Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiL’annotazione @overrideLa parola chiave final per le classiCostruttori ed ereditarietàRiepilogo - Gerarchia dei dipendenti9Polimorfismo
Fondamenti di polimorfismoPolimorfismo tramite interfacceControllo del tipo a runtimeGli operatori is e asParola chiave covariantRiepilogo - Elaboratore di pagamenti12OOP asincrona
Future e async/awaitNozioni di base sugli streamController degli streamCostruttori asincroniAsync nei metodi di classeRiepilogo - Recupero dei dati15Pattern di progettazione Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern RepositoryEsercitati da solo: Compilatore Dart online