Null Safety và Nullable Types
🎯 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
Phần tiêu đề “💡 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ể nullString? nullableName; // Có thể null📝 Non-nullable vs Nullable
Phần tiêu đề “📝 Non-nullable vs Nullable”// Non-nullable - phải có giá trịint count = 0;// count = null; // Error!
// Nullable - có thể nullint? nullableCount;nullableCount = null; // OKnullableCount = 10; // OK🔧 Null-aware Operators
Phần tiêu đề “🔧 Null-aware Operators”?. - Conditional access
Phần tiêu đề “?. - Conditional access”String? name;print(name?.length); // null (không crash)
String name2 = "Dart";print(name2.length); // 4?? - Null coalescing (If-null)
Phần tiêu đề “?? - Null coalescing (If-null)”String? name;String displayName = name ?? "Guest";print(displayName); // Guest??= - Null-aware assignment
Phần tiêu đề “??= - Null-aware assignment”String? name;name ??= "Default"; // Gán nếu nullprint(name); // Default! - Null assertion
Phần tiêu đề “! - 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
Phần tiêu đề “🎯 Late Variables”late String description; // Sẽ khởi tạo sau
void initialize() { description = "Initialized";}
// Lazy initializationlate final int value = computeExpensiveValue();🔍 Flow Analysis
Phần tiêu đề “🔍 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
Phần tiêu đề “🛠️ 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 = "user@example.com";
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
Phần tiêu đề “📱 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 tiêu đề “✅ Checklist”- Phân biệt
StringvsString? - Sử dụng
?.cho safe access - Sử dụng
??cho default values - Hiểu
latecho lazy initialization - Tránh lạm dụng
!(null assertion)
Tiếp theo: In kết quả với print()