Menu
CoddyTech

Có thể null và không thể null

Thuộc phần Lập trình hướng đối tượng trong hành trình Dart của Coddy. Bài học 24 trên 110.

Giờ bạn đã hiểu vì sao tính an toàn với giá trị null lại quan trọng, hãy cùng tìm hiểu cách khai báo biến có thể chứa giá trị null. Trong Dart, bạn thêm ? sau tên kiểu dữ liệu để cho phép kiểu đó nhận giá trị null.

String name = 'Alice';   // Không thể là null, luôn phải có giá trị
String? nickname;        // Có thể là null hoặc một String

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

Điểm khác biệt chính là kiểu không thể null đảm bảo luôn có giá trị, còn kiểu có thể null cho phép rõ ràng việc không có giá trị. Sự khác biệt này áp dụng cho tất cả các kiểu dữ liệu:

int count = 10;       // Phải có giá trị
int? optionalCount;   // Có thể là null

List<String> items = [];      // Phải là danh sách (có thể rỗng)
List<String>? maybeItems;     // Có thể là null (không có danh sách nào)

Lưu ý rằng danh sách rỗng [] khác với null. Danh sách rỗng vẫn tồn tại nhưng không chứa gì; null nghĩa là hoàn toàn không có danh sách nào.

Trình biên dịch thực thi nghiêm ngặt các quy tắc này. Bạn không thể gán null cho một biến không thể nhận giá trị null, và không thể dùng một biến có thể nhận giá trị null ở nơi cần biến không thể nhận giá trị null nếu chưa kiểm tra giá trị null:

String? maybeName = 'Bob';
// String definite = maybeName;  // Lỗi! Không thể gán giá trị có thể null cho biến không chấp nhận null

Trong bài học tiếp theo, bạn sẽ tìm hiểu các toán tử mà Dart cung cấp để làm việc an toàn với các giá trị có thể là null.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống danh sách phim muốn xem để minh họa sự khác biệt giữa thông tin bắt buộc và thông tin tùy chọn bằng cách dùng các kiểu nullable và non-nullable.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • movie.dart: Định nghĩa lớp Movie đại diện cho một bộ phim trong danh sách muốn xem. Mỗi phim phải có tiêu đề và năm phát hành (đây luôn là thông tin bắt buộc), nhưng có thể không có một số thông tin bổ sung. Lớp của bạn cần có:
    • String title non-nullable, mỗi phim phải có tiêu đề
    • int year non-nullable, mỗi phim phải có năm phát hành
    • String? director nullable, có thể không biết đạo diễn
    • double? rating nullable, chưa phải phim nào cũng có điểm đánh giá
    • Một hàm khởi tạo nhận title và year làm tham số bắt buộc
    • Một phương thức displayInfo() in thông tin phim, hiển thị Unknown nếu thiếu đạo diễn và Not rated nếu thiếu điểm đánh giá
  • main.dart: Import lớp phim của bạn và tạo một danh sách phim ngắn, minh họa cả dữ liệu phim đầy đủ lẫn chưa đầy đủ:
    • Tạo một phim có tiêu đề 'Inception' và năm 2010, sau đó đặt đạo diễn là 'Christopher Nolan' và điểm đánh giá là 8.8
    • Tạo một phim có tiêu đề 'The Matrix' và năm 1999, sau đó chỉ đặt điểm đánh giá là 8.7 (để đạo diễn là null)
    • Tạo một phim có tiêu đề 'Upcoming Film' và năm 2025 (để cả đạo diễn lẫn điểm đánh giá là null)
    • Gọi displayInfo() cho từng phim theo thứ tự liệt kê ở trên

Phương thức displayInfo() cần in theo đúng định dạng sau:

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

Hãy lưu ý rằng các trường non-nullable (title và year) luôn có giá trị, còn các trường nullable (director? và rating?) có thể không được thiết lập. Điều này phản ánh các tình huống thực tế, trong đó một số dữ liệu là thiết yếu còn một số khác là tùy chọn.

Đầu ra dự kiến:

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

Tự làm thử

import 'movie.dart';

void main() {
  // TODO: Tạo một phim có tiêu đề 'Inception' và năm 2010
  // Sau đó đặt director thành 'Christopher Nolan' và rating thành 8.8
  
  // TODO: Tạo một phim có tiêu đề 'The Matrix' và năm 1999
  // Sau đó chỉ đặt rating thành 8.7 (giữ director là null)
  
  // TODO: Tạo một phim có tiêu đề 'Upcoming Film' và năm 2025
  // Giữ cả director và rating là null
  
  // TODO: Gọi displayInfo() cho từng phim theo thứ tự
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Dart online