Bỏ qua để đến nội dung

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.


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 - phải có giá trị
int count = 0;
// count = null; // Error!
// Nullable - có thể null
int? nullableCount;
nullableCount = null; // OK
nullableCount = 10; // OK

String? name;
print(name?.length); // null (không crash)
String name2 = "Dart";
print(name2.length); // 4
String? name;
String displayName = name ?? "Guest";
print(displayName); // Guest
String? name;
name ??= "Default"; // Gán nếu null
print(name); // Default
String? name = "Dart";
int length = name!.length; // Assert not null
// Cẩn thận!
String? nullName;
// int len = nullName!.length; // Runtime error!

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

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!
}

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");
}
}

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),
],
);
}
}

  • 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()