Skip to Content
Dart📘 Ngôn ngữ DartNull Safety và Nullable Types

Null Safety trong Dart

🎯 Mục tiêu: Hiểu Sound Null Safety - tính năng quan trọng của Dart giúp loại bỏ null errors.


💡 Khái niệm

Từ Dart 2.12, mọi biến mặc định non-nullable. Phải khai báo tường minh nếu muốn cho phép null.

String name = "Dart"; // Không thể null String? nullableName; // Có thể null

📝 Non-nullable vs Nullable

// Non-nullable - phải có giá trị int count = 0; // count = null; // Error! // Nullable - có thể null int? nullableCount; nullableCount = null; // OK nullableCount = 10; // OK

🔧 Null-aware Operators

?. - Conditional access

String? name; print(name?.length); // null (không crash) String name2 = "Dart"; print(name2.length); // 4

?? - Null coalescing (If-null)

String? name; String displayName = name ?? "Guest"; print(displayName); // Guest

??= - Null-aware assignment

String? name; name ??= "Default"; // Gán nếu null print(name); // Default

! - Null assertion

String? name = "Dart"; int length = name!.length; // Assert not null // Cẩn thận! String? nullName; // int len = nullName!.length; // Runtime error!

🎯 Late Variables

late String description; // Sẽ khởi tạo sau void initialize() { description = "Initialized"; } // Lazy initialization late final int value = computeExpensiveValue();

🔍 Flow Analysis

Dart tự động track null status:

void process(String? name) { if (name == null) { print("No name"); return; } // Dart biết name không null ở đây print(name.length); // OK, không cần name! }

🛠️ Thực hành

void main() { String? email; // TODO: In domain của email hoặc "No email" }

Lời giải:

void main() { String? email = "[email protected]"; String domain = email?.split("@").last ?? "No email"; print(domain); // example.com // Hoặc với flow analysis if (email != null) { print(email.split("@").last); } else { print("No email"); } }

📱 Trong Flutter

class UserProfile extends StatelessWidget { final String? avatarUrl; final String name; const UserProfile({ required this.name, this.avatarUrl, // Optional }); @override Widget build(BuildContext context) { return Column( children: [ // Null check cho image if (avatarUrl != null) Image.network(avatarUrl!) else Icon(Icons.person), Text(name), ], ); } }

✅ Checklist

  • Phân biệt String vs String?
  • Sử dụng ?. cho safe access
  • Sử dụng ?? cho default values
  • Hiểu late cho lazy initialization
  • Tránh lạm dụng ! (null assertion)

Tiếp theo: In kết quả với print()

Last updated on