Menu
Coddy logo textTech

Typy dopuszczające null i niedopuszczające null

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 24 z 110.

Skoro już rozumiesz, dlaczego bezpieczeństwo null ma znaczenie, zobaczmy, jak zadeklarować zmienne, które mogą przechowywać wartość null. W Dart możesz sprawić, że typ będzie dopuszczał wartość null, dodając ? po nazwie typu.

String name = 'Alice';   // Nieakceptujący wartości null — zawsze musi mieć wartość
String? nickname;        // Akceptujący wartość null — może być null lub typu String

print(name);      // Alice
print(nickname);  // null

Kluczowa różnica polega na tym, że typy niepuste gwarantują istnienie wartości, natomiast typy dopuszczające wartość null jawnie pozwalają na jej brak. To rozróżnienie dotyczy wszystkich typów:

int count = 10;       // Musi mieć wartość
int? optionalCount;   // Może mieć wartość null

List<String> items = [];      // Musi być listą (może być pusta)
List<String>? maybeItems;     // Może mieć wartość null (lista może w ogóle nie istnieć)

Zauważ, że pusta lista [] różni się od null. Pusta lista istnieje, ale niczego nie zawiera; null oznacza, że żadna lista w ogóle nie istnieje.

Kompilator ściśle egzekwuje te zasady. Nie możesz przypisać wartości null do zmiennej, która nie dopuszcza wartości null, ani użyć zmiennej, która dopuszcza wartość null, w miejscu, w którym oczekiwana jest zmienna niedopuszczająca wartości null, bez uprzedniego sprawdzenia, czy jej wartość to null:

String? maybeName = 'Bob';
// String definite = maybeName;  // Błąd! Nie można przypisać wartości dopuszczającej null do typu niedopuszczającego null

W następnej lekcji poznasz operatory, które Dart udostępnia, aby bezpiecznie pracować z wartościami dopuszczającymi null.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system listy filmów do obejrzenia, który pokazuje różnicę między informacjami wymaganymi a opcjonalnymi, używając typów dopuszczających i niedopuszczających wartości null.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • movie.dart: Zdefiniuj klasę Movie, która reprezentuje film na Twojej liście do obejrzenia. Każdy film musi mieć tytuł i rok premiery (są one zawsze wymagane), ale niektóre dodatkowe informacje mogą być niedostępne dla każdego filmu. Twoja klasa powinna zawierać:
    • Pole String title, które nie dopuszcza wartości null — każdy film musi mieć tytuł
    • Pole int year, które nie dopuszcza wartości null — każdy film musi mieć rok premiery
    • Pole String? director, które dopuszcza wartość null — reżyser może być nieznany
    • Pole double? rating, które dopuszcza wartość null — nie wszystkie filmy zostały już ocenione
    • Konstruktor, który przyjmuje title i year jako wymagane parametry
    • Metodę displayInfo(), która wyświetla informacje o filmie, pokazując Unknown, gdy brakuje reżysera, oraz Not rated, gdy brakuje oceny
  • main.dart: Zaimportuj swoją klasę filmu i utwórz krótką listę do obejrzenia, pokazującą zarówno kompletne, jak i niekompletne dane filmów:
    • Utwórz film z tytułem 'Inception' i rokiem 2010, a następnie ustaw jego reżysera na 'Christopher Nolan' i ocenę na 8.8
    • Utwórz film z tytułem 'The Matrix' i rokiem 1999, a następnie ustaw tylko jego ocenę na 8.7 (pozostaw reżysera jako null)
    • Utwórz film z tytułem 'Upcoming Film' i rokiem 2025 (pozostaw zarówno reżysera, jak i ocenę jako null)
    • Wywołaj displayInfo() dla każdego filmu, w podanej wyżej kolejności

Metoda displayInfo() powinna wyświetlać informacje w dokładnie takim formacie:

[title] ([year])
Director: [director or "Unknown"]
Rating: [rating or "Not rated"]

Zwróć uwagę, że pola niedopuszczające wartości null (title i year) zawsze mają przypisane wartości, podczas gdy pola dopuszczające wartość null (director? i rating?) mogą pozostać nieustawione. Odzwierciedla to rzeczywiste sytuacje, w których niektóre dane są niezbędne, a inne opcjonalne.

Oczekiwany wynik:

Inception (2010)
Director: Christopher Nolan
Rating: 8.8
The Matrix (1999)
Director: Unknown
Rating: 8.7
Upcoming Film (2025)
Director: Unknown
Rating: Not rated

Spróbuj swoich sił

import 'movie.dart';

void main() {
  // TODO: Utwórz film o tytule 'Inception' z roku 2010
  // Następnie ustaw jego reżysera na 'Christopher Nolan', a ocenę na 8.8
  
  // TODO: Utwórz film o tytule 'The Matrix' z roku 1999
  // Następnie ustaw tylko jego ocenę na 8.7 (pozostaw director jako null)
  
  // TODO: Utwórz film o tytule 'Upcoming Film' z roku 2025
  // Pozostaw zarówno director, jak i rating jako null
  
  // TODO: Wywołaj displayInfo() dla każdego filmu po kolei
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online