Operatory uwzględniające null
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 27 z 110.
Oprócz ?. i ! Dart udostępnia dodatkowe operatory, które pozwalają zwięźlej pracować z wartościami dopuszczającymi wartość null. Te operatory uwzględniające null pomagają pisać czytelniejszy kod podczas obsługi potencjalnych wartości null.
Operator koalescencji null ?? zwraca lewą wartość, jeśli nie jest null, w przeciwnym razie zwraca prawą wartość:
String? nickname;
String displayName = nickname ?? 'Guest';
print(displayName); // Guest
nickname = 'Alex';
displayName = nickname ?? 'Guest';
print(displayName); // AlexOperator przypisania uwzględniający null ??= przypisuje wartość tylko wtedy, gdy zmienna ma obecnie wartość null:
String? username;
username ??= 'Anonymous';
print(username); // Anonymous
username ??= 'NewName';
print(username); // Nadal Anonymous (nie było null)Możesz łączyć operator dostępu uwzględniający wartości null ?. dla zagnieżdżonych właściwości:
String? city = user?.address?.city; // Bezpieczne, nawet jeśli user lub address ma wartość nullTe operatory dobrze ze sobą współpracują. Na przykład możesz uzyskać dostęp do właściwości dopuszczającej wartość null i podać wartość domyślną:
String greeting = user?.name ?? 'Stranger';
// Jeśli user jest null LUB user.name jest null, użyj 'Stranger'Używanie tych operatorów sprawia, że kod pozostaje czytelny, a jednocześnie zapewnia bezpieczeństwo obsługi wartości null w całym programie.
Wyzwanie
ŁatwyStwórzmy system rejestracji gości, który pokazuje, jak operatory obsługujące wartości null mogą uprościć kod podczas pracy z opcjonalnymi informacjami.
Podzielisz kod na dwa pliki:
guest.dart: Zdefiniuj klasęGuest, która reprezentuje osobę uczestniczącą w wydarzeniu. Niektórzy goście podają wszystkie dane, a inni tylko podstawowe informacje. Twoja klasa powinna zawierać:- Nieprzyjmującą wartości null zmienną
String name— każdy gość musi mieć imię - Przyjmującą wartość null zmienną
String? email— nie każdy podaje adres e-mail - Przyjmującą wartość null zmienną
String? dietaryPreference— niektórzy goście nie określają wymagań żywieniowych - Konstruktor, który przyjmuje
namejako wymagany parametr - Metodę
getDisplayEmail(), która zwraca adres e-mail, jeśli jest dostępny, lub'No email provided', używając operatora?? - Metodę
assignDefaultDiet(), która ustawiadietaryPreferencena'Standard'tylko wtedy, gdy jego bieżąca wartość to null, używając operatora??= - Metodę
getEmailDomain(), która zwraca długość adresu e-mail, używając?., lubnull, jeśli adres e-mail nie istnieje - Metodę
printBadge(), która wyświetla informacje z identyfikatora gościa
- Nieprzyjmującą wartości null zmienną
main.dart: Zaimportuj klasę gościa i zarejestruj trzech gości o różnym poziomie wypełnienia danych:- Utwórz gościa o imieniu
'Alice', ustaw jej adres e-mail na'alice@company.com', a wymagania żywieniowe na'Vegetarian' - Utwórz gościa o imieniu
'Bob', ustaw tylko jego adres e-mail na'bob@email.org'(pozostaw wymagania żywieniowe jako null) - Utwórz gościa o imieniu
'Charlie'(pozostaw zarówno adres e-mail, jak i wymagania żywieniowe jako null) - Wywołaj
assignDefaultDiet()dla wszystkich trzech gości - Dla każdego gościa, w podanej kolejności, wywołaj
printBadge(), a następnie wyświetlEmail length: [result], używającgetEmailDomain()
- Utwórz gościa o imieniu
Metoda printBadge() powinna wyświetlać informacje w następującym formacie:
=== Guest Badge ===
Name: [name]
Email: [getDisplayEmail()]
Diet: [dietaryPreference or "Not specified"]Zauważ, że wymagania żywieniowe Alice pozostają ustawione na 'Vegetarian', ponieważ ??= przypisuje wartość tylko wtedy, gdy bieżąca wartość to null, podczas gdy Bob i Charlie otrzymują domyślną dietę 'Standard'.
Oczekiwany wynik:
=== Guest Badge ===
Name: Alice
Email: alice@company.com
Diet: Vegetarian
Email length: 17
=== Guest Badge ===
Name: Bob
Email: bob@email.org
Diet: Standard
Email length: 13
=== Guest Badge ===
Name: Charlie
Email: No email provided
Diet: Standard
Email length: nullSpróbuj swoich sił
import 'guest.dart';
void main() {
// TODO: Utwórz gościa o imieniu 'Alice'
// Ustaw jej adres e-mail na 'alice@company.com'
// Ustaw jej preferencję żywieniową na 'Vegetarian'
// TODO: Utwórz gościa o imieniu 'Bob'
// Ustaw tylko jego adres e-mail na 'bob@email.org'
// Pozostaw preferencję żywieniową jako null
// TODO: Utwórz gościa o imieniu 'Charlie'
// Pozostaw zarówno adres e-mail, jak i preferencję żywieniową jako null
// TODO: Wywołaj assignDefaultDiet() dla wszystkich trzech gości
// TODO: Dla każdego gościa w podanej kolejności (Alice, Bob, Charlie):
// - Wywołaj printBadge()
// - Wypisz 'Email length: [result]', używając getEmailDomain()
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP
Pliki zewnętrzneBiblioteki i importyWprowadzenie do OOPKlasy a obiektySłowo kluczowe thisMetodyZmienne instancjiPodstawy konstruktorówPowtórka – prosty kalkulator4Bezpieczeństwo wartości null
Wprowadzenie do bezpieczeństwa wartości nullTypy dopuszczające null i niedopuszczające nullOperatory ? i !Słowo kluczowe late a bezpieczeństwo wartości nullOperatory uwzględniające nullBezpieczeństwo wartości null w klasachPodsumowanie — system profili użytkowników7Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjneMetody abstrakcyjneInterfejsy w DartInterfejsy niejawneImplementowanie a rozszerzanieWiele interfejsówPowtórka — kalkulator kształtów10Kolekcje i typy generyczne
Przegląd List, Set i MapKolekcje bezpieczne typowoKlasy generyczneMetody generyczneOgraniczenia typów generycznychIterable i IteratorPowtórka — generyczne przechowywanie danych13Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieMetody rozszerzająceKlasy wywoływalneKlasy zapieczętowane (Dart 3)Rekordy (Dart 3)Wzorce i dopasowywanie (3.0)Typy wyliczeniowe z metodami16Projekt: Zarządzanie biblioteką
Omówienie projektuKlasy książek i użytkowników2Konstruktory w Dart
Konstruktor domyślnyKonstruktory nazwaneListy inicjalizująceKonstruktory stałeKonstruktory fabryczneKonstruktory przekierowującePodsumowanie — budowanie kształtów5Hermetyzacja
Elementy publiczne a prywatneKonwencja prefiksu _Prywatność na poziomie bibliotekiGettery i settery — szczegółowoUkrywanie informacjiPodsumowanie — dane uczniów8Domieszki
Wprowadzenie do domieszekTworzenie domieszekKorzystanie z wielu domieszekSłowo kluczowe on w domieszkachDomieszka a dziedziczenieDomieszka a interfejsPodsumowanie – system zwierząt11Metody specjalne
Nadpisanie toString()Nadpisanie hashCode i ==Interfejs ComparableMetoda call()Nadpisanie noSuchMethodPodsumowanie — własna kolekcja14Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy3Właściwości klas
Elementy instancji a elementy statycznePola final i constZmienne inicjalizowane z opóźnieniemMetody i pola statyczneGettery i setteryPowtórzenie – menedżer kont bankowych6Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superPrzesłanianie metodAdnotacja @overrideSłowo kluczowe final dla klasKonstruktory i dziedziczeniePowtórzenie – hierarchia pracowników9Polimorfizm
Podstawy polimorfizmuPolimorfizm za pomocą interfejsówSprawdzanie typu w czasie działaniaOperatory is i asSłowo kluczowe covariantPodsumowanie — procesor płatnościPoćwicz samodzielnie: Kompilator Dart online