null safety in Dart

ميزة Null Safety من أهم التحديثات في لغة Dart، وهي أساسية جدًا خاصة عند بناء تطبيقات Flutter وDart الحديثة.

✅ ما هي Null Safety؟

Null Safety تعني:

حماية الكود من الوصول إلى متغيرات قيمها null مما يؤدي إلى أخطاء أثناء التشغيل (runtime).

بكلمات أبسط:
Dart تمنعك من ترك متغير بدون قيمة (null) إلا إذا طلبت أنت ذلك صراحة.

✳️ لماذا Null Safety مهمة؟

قبل Null Safety، كانت Dart تسمح لأي متغير أن يكون null. وهذا يؤدي إلى أشهر خطأ في البرمجة:

NullPointerException
Dart
🧩 الفرق بين Null و Non-Null
التعريفالشرح
int x = 5;لا يمكن أن تكون x null
int? x = null;يمكن أن تكون x null (لاحظ علامة ?)
✳️ تعريف المتغيرات
✅ متغير غير قابل أن يكون null:
String name = "Ali";
name = "Sara";  // ✅ مسموح
// name = null; // ❌ خطأ
Dart
✅ متغير قابل أن يكون null:
String? name = null; // ✅ مسموح
name = "Omar";
Dart

📌 لاحظ استخدام ? بعد نوع المتغير.

✳️ التعامل مع القيم القابلة أن تكون null
1. التحقق قبل الاستخدام
String? name = getName();

if (name != null) {
  print(name.length); // ✅ آمن
}
Dart
2. استخدام الـ null-aware operator ?.
String? name = null;

print(name?.length); // ✅ لن يُطبع شيء ولن يحدث خطأ
Dart
  • ?. تعني: إذا name ليست null → نفذ length، وإلا لا تفعل شيء.
3. Null coalescing operator (??)
String? name = null;
String finalName = name ?? "غير معروف";

print(finalName); // غير معروف
Dart
  • ?? تعني: إذا كانت name null → استخدم القيمة الافتراضية.
4. فرض أن المتغير غير null (!)
String? name = "Ali";
print(name!.length); // ✅ يعمل لكن احذر ⚠️
Dart
  • ! تعني: “أنا متأكد أن القيمة ليست null”
  • ⚠️ إذا كانت null → سيحدث خطأ وقت التشغيل.
✳️ Null Safety مع الدوال
✅ دالة تُعيد null
String? getUserName() {
  return null;
}
Dart
✅ دالة تقبل قيمة يمكن أن تكون null
void greet(String? name) {
  if (name != null) {
    print("Hello $name");
  }
}
Dart
✳️ Null Safety مع القوائم:
List<String?> names = ["Ali", null, "Sara"];
for (var name in names) {
  print(name ?? "غير معروف");
}
Dart
  • هذه قائمة تحتوي عناصر قابلة أن تكون null.
✳️ Null Safety مع الكائنات (Objects)
class User {
  String? name;
  int age;

  User(this.age);
}

void main() {
  var user = User(30);
  user.name = "Ali";
  print(user.name?.toUpperCase()); // ✅
}
Dart
✳️ Late Keyword

late تعني: سأقوم بتهيئة المتغير لاحقًا، لكنه لن يكون null عند استخدامه.

late String name;

void main() {
  name = "Ali";
  print(name); // ✅ لا خطأ
}
Dart
  • مفيدة عندما تعرف أنك ستهيئ المتغير، لكن ليس فورًا.
❌ أمثلة لأخطاء Null Safety
String name;
print(name); // ❌ خطأ: يجب تهيئته قبل الاستخدام

String? name = null;
print(name.length); // ❌ خطأ: لا يمكن استخدام length مباشرة
Dart
✅ تلخيص سريع
الصيغةالمعنى
Stringغير مسموح أن تكون null
String?مسموح أن تكون null
name!فرض أن القيمة ليست null (احذر ⚠️)
name?.xتنفيذ x إذا كانت name غير null
name ?? valueإذا كانت name null استخدم value
lateتهيئة متأخرة ولكن غير null
📘 أفضل الممارسات
  1. استخدم المتغيرات غير القابلة لـ null كلما أمكن (String name)
  2. استخدم String? فقط إذا كنت تحتاج فعلاً قيمة قد تكون null.
  3. تجنب استخدام ! إلا إذا كنت متأكد 100%.
  4. استخدم ?? و ?. لتفادي الأخطاء الشائعة.