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
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()
Last updated on