Die Operatoren ? und !
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
EinfachLass uns ein Produktinventarsystem erstellen, das zeigt, wie man mit den Operatoren ?. und ! sicher mit möglicherweise nullbaren Werten arbeitet.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
product.dart: Definiere eineProduct-Klasse, die einen Artikel im Inventar darstellt. Einige Produkte verfügen über vollständige Informationen, während andere noch erfasst werden. Deine Klasse sollte Folgendes enthalten:- Einen nicht nullbaren
String name– jedes Produkt muss einen Namen haben - Einen nicht nullbaren
double price– jedes Produkt muss einen Preis haben - Eine nullable
String? description– einige Produkte haben noch keine Beschreibung - Eine nullable
String? category– einige Produkte wurden noch keiner Kategorie zugeordnet - Einen Konstruktor, der
nameundpriceals erforderliche Parameter entgegennimmt - Eine Methode
getDescriptionLength(), die mithilfe von?.die Länge der Beschreibung zurückgibt odernull, wenn keine Beschreibung vorhanden ist - Eine Methode
getCategoryUppercase(), die mithilfe von!die Kategorie in Großbuchstaben zurückgibt – diese Methode setzt voraus, dass die Kategorie gesetzt wurde - Eine Methode
displayProduct(), die die Produktinformationen ausgibt undNo descriptionanzeigt, wenn die Beschreibung null ist, sowieUncategorized, wenn die Kategorie null ist
- Einen nicht nullbaren
main.dart: Importiere deine Produktklasse und demonstriere beide Operatoren:- Erstelle ein Produkt mit dem Namen
'Laptop'und dem Preis999.99, setze anschließend seine Beschreibung auf'High-performance computing device'und seine Kategorie auf'Electronics' - Erstelle ein Produkt mit dem Namen
'Mystery Item'und dem Preis49.99(lasse Beschreibung und Kategorie auf null) - Für den Laptop: Rufe
displayProduct()auf, gibDescription length: [length]mithilfe vongetDescriptionLength()aus und gibCategory: [uppercase]mithilfe vongetCategoryUppercase()aus - Für das Mystery Item: Rufe
displayProduct()auf und gibDescription length: [length]mithilfe vongetDescriptionLength()aus (dies wirdnullanzeigen)
- Erstelle ein Produkt mit dem Namen
Die Methode displayProduct() sollte in diesem Format ausgeben:
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: nullProbier 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 Schlüsselwort thisMethodenInstanzvariablenGrundlagen von KonstruktorenRückblick – Einfacher Taschenrechner4Null-Sicherheit
Einführung in die Null-SicherheitNullable vs. Non-NullableDie Operatoren ? und !Late-Schlüsselwort und Null-SicherheitNull-bewusste OperatorenNull-Sicherheit in KlassenRückblick – Benutzers профilsystem7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrere InterfacesZusammenfassung – Formrechner10Collections & Generics
Übersicht über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische EinschränkungenIterable & IteratorRückblick – Generischer Speicher13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungErweiterungsmethodenAufrufbare KlassenVersiegelte Klassen (Dart 3)Records (Dart 3)Muster & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
StandardkonstruktorBenannte KonstruktorenInitialisierungslistenKonstantenkonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenRückblick – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _-Präfix-KonventionBibliotheksweite SichtbarkeitTiefergehende Getter & SetterInformationsverbergungRückblick – Studierendendaten8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas Schlüsselwort „on“ in MixinsMixin vs. VererbungMixin vs. SchnittstelleRückblick – Tiersystem11Spezielle Methoden
toString()-ÜberschreibunghashCode- & ==-ÜberschreibungComparable-Schnittstellecall()-MethodenoSuchMethod-ÜberschreibungWiederholung – Benutzerdefinierte Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFabrikmusterBeobachtermusterStrategiemuster17Abschließende Herausforderungen
E-Learning-PlattformBankingsystemSpielcharaktersystemFahrzeugvermietung3Klassen-Eigenschaften
Instanz- vs. statische MemberFinal- und Const-FelderLate-VariablenStatische Methoden und FelderGetter und SetterRückblick – Bankkontoverwaltung6Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungDie Annotation @overrideDas Schlüsselwort final für KlassenKonstruktoren und VererbungZusammenfassung – Mitarbeiterhierarchie9Polymorphismus
Grundlagen des PolymorphismusPolymorphismus über InterfacesLaufzeit-TypüberprüfungDie Operatoren is & asCovariant-SchlüsselwortZusammenfassung – ZahlungsprozessorÜbe selbstständig: Online-Dart-Compiler