Die ? und ! Operatoren
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 25 von 110.
Beim Arbeiten mit Nullable-Typen bietet Dart zwei wesentliche Operatoren, um sicher auf Werte zuzugreifen. Der null-aware Zugriffsoperator ?. und der Null-Assertion-Operator ! geben Ihnen die Kontrolle darüber, wie Sie mit potenziell nullwertigen Werten umgehen.
Der ?.-Operator greift sicher auf Eigenschaften oder Methoden eines Nullable-Werts zu. Wenn der Wert null ist, gibt der gesamte Ausdruck null zurück, anstatt abzustürzen:
String? name = 'Alice';
print(name?.length); // 5
name = null;
print(name?.length); // null (kein Absturz!)Der !-Operator teilt Dart mit: „Ich bin sicher, dass dieser Wert nicht null ist.“ Er konvertiert einen Nullable-Typ in einen Non-Nullable-Typ, wirft jedoch einen Fehler, wenn der Wert tatsächlich null ist:
String? maybeName = 'Bob';
String definite = maybeName!; // OK - wir versichern, dass es nicht null ist
print(definite.length); // 3
String? empty = null;
// String crash = empty!; // Laufzeitfehler! Wert war nullVerwenden Sie ?., wenn Sie Null-Werte elegant behandeln möchten. Verwenden Sie ! nur dann, wenn Sie absolut sicher sind, dass ein Wert existiert – vielleicht nachdem Sie ihn mit einer if-Anweisung überprüft haben oder wenn Sie wissen, dass die Logik einen Wert garantiert. Die übermäßige Verwendung von ! macht den Zweck der Null-Sicherheit zunichte und kann zu Abstürzen zur Laufzeit führen.
Aufgabe
EinfachLassen Sie uns ein Produktinventarsystem erstellen, das zeigt, wie man mit den Operatoren ?. und ! sicher mit Nullable-Werten arbeitet.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
product.dart: Definieren Sie eine KlasseProduct, die einen Artikel im Inventar darstellt. Einige Produkte haben vollständige Informationen, während andere noch katalogisiert werden. Ihre Klasse sollte Folgendes enthalten:- Ein nicht-nullable
String name- jedes Produkt muss einen Namen haben - Ein nicht-nullable
double price- jedes Produkt muss einen Preis haben - Ein nullable
String? description- einige Produkte haben noch keine Beschreibungen - Ein nullable
String? category- einige Produkte wurden noch nicht kategorisiert - Einen Konstruktor, der
nameundpriceals erforderliche Parameter entgegennimmt - Eine Methode
getDescriptionLength(), die die Länge der Beschreibung unter Verwendung von?.zurückgibt, odernull, wenn keine Beschreibung vorhanden ist - Eine Methode
getCategoryUppercase(), die die Kategorie in Großbuchstaben unter Verwendung von!zurückgibt - diese Methode geht davon aus, dass die Kategorie gesetzt wurde - Eine Methode
displayProduct(), die die Produktinformationen ausgibt und"No description"anzeigt, wenn die Beschreibung null ist, und"Uncategorized", wenn die Kategorie null ist
- Ein nicht-nullable
main.dart: Importieren Sie Ihre Produktklasse und demonstrieren Sie beide Operatoren:- Erstellen Sie ein Produkt mit dem Namen
'Laptop'und dem Preis999.99, setzen Sie dann die Beschreibung auf'High-performance computing device'und die Kategorie auf'Electronics' - Erstellen Sie ein Produkt mit dem Namen
'Mystery Item'und dem Preis49.99(lassen Sie Beschreibung und Kategorie auf null) - Für den Laptop: Rufen Sie
displayProduct()auf, geben SieDescription length: [length]unter Verwendung vongetDescriptionLength()aus und geben SieCategory: [uppercase]unter Verwendung vongetCategoryUppercase()aus - Für das Mystery Item: Rufen Sie
displayProduct()auf und geben SieDescription length: [length]unter Verwendung vongetDescriptionLength()aus (dies wirdnullanzeigen)
- Erstellen Sie ein Produkt mit dem Namen
Die Methode displayProduct() sollte in diesem Format drucken:
Product: [name] - $[price]
Description: [description or "No description"]
Category: [category or "Uncategorized"]Erwartete Ausgabe:
Product: Laptop - $999.99
Description: High-performance computing device
Category: Electronics
Description length: 32
Category: ELECTRONICS
Product: Mystery Item - $49.99
Description: No description
Category: Uncategorized
Description length: nullSpickzettel
Der Null-Aware-Zugriffsoperator ?. greift sicher auf Eigenschaften oder Methoden von Nullable-Werten zu. Wenn der Wert null ist, gibt er null zurück, anstatt einen Fehler auszulösen:
String? name = 'Alice';
print(name?.length); // 5
name = null;
print(name?.length); // null (kein Absturz!)Der Null-Assertion-Operator ! konvertiert einen Nullable-Typ in einen Non-Nullable-Typ. Verwenden Sie ihn nur, wenn Sie sicher sind, dass der Wert nicht null ist, da er einen Laufzeitfehler auslöst, wenn der Wert tatsächlich null ist:
String? maybeName = 'Bob';
String definite = maybeName!; // OK - bestätigt, dass es nicht null ist
print(definite.length); // 3
String? empty = null;
// String crash = empty!; // Laufzeitfehler!Verwenden Sie ?. für eine elegante Null-Behandlung und ! nur dann, wenn Sie absolut sicher sind, dass ein Wert existiert.
Probier es selbst
import 'product.dart';
void main() {
// TODO: Erstelle ein Produkt namens 'Laptop' mit dem Preis 999.99
// Setze dann seine Beschreibung auf 'High-performance computing device'
// Und setze seine Kategorie auf 'Electronics'
// TODO: Erstelle ein Produkt namens 'Mystery Item' mit dem Preis 49.99
// Lasse Beschreibung und Kategorie als null
// TODO: Für den Laptop:
// - Rufe displayProduct() auf
// - Drucke "Description length: [length]" unter Verwendung von getDescriptionLength()
// - Drucke "Category: [uppercase]" unter Verwendung von getCategoryUppercase()
// TODO: Für das Mystery Item:
// - Rufe displayProduct() auf
// - Drucke "Description length: [length]" unter Verwendung von getDescriptionLength()
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienBibliotheken & ImportsEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenInstanzvariablenKonstruktor-GrundlagenWiederholung – Einfacher Taschenrechner4Null-Sicherheit
Einführung in Null-SicherheitNullable vs. Non-NullableDie ? und ! OperatorenLate-Schlüsselwort & Null-SicherheitNull-aware OperatorenNull-Sicherheit in KlassenZusammenfassung – Benutzerprofil-System7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrfache InterfacesRückblick – Shape Calculator10Collections & Generics
Überblick über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische ConstraintsIterable & IteratorZusammenfassung – Generische Speicherung13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
Standard-KonstruktorBenannte KonstruktorenInitialisierungslistenKonstante KonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenZusammenfassung – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _ Präfix-KonventionSichtbarkeit auf Library-EbeneGetter & Setter im DetailInformation HidingRückblick – Schülerdatensätze8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas on-Schlüsselwort in MixinsMixin vs. VererbungMixin vs. InterfaceZusammenfassung - Tiersystem11Spezielle Methoden
toString() überschreibenhashCode & == überschreibenComparable-Interfacecall()-MethodenoSuchMethod überschreibenZusammenfassung – Eigene Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster3Klasseneigenschaften
Instanz- vs. statische MemberFinal & Const FelderLate-VariablenStatische Methoden & FelderGetter und SetterZusammenfassung – Bankkonto-Manager6Vererbung
Grundlagen der VererbungDas super-SchlüsselwortMethoden überschreibenDie @override-AnnotationDas final-Klassen-SchlüsselwortKonstruktoren & VererbungRückblick – Mitarbeiter-Hierarchie9Polymorphismus
Polymorphismus-GrundlagenPolymorphismus über InterfacesTypprüfung zur LaufzeitDie is & as OperatorenDas covariant SchlüsselwortZusammenfassung – Payment Processor