الأمان من القيم الفارغة (Null Safety) من أهمّ ما يميّز Dart الحديثة، وهو يمنع فئةً كاملة من الأخطاء الشائعة. تبني هذه الصفحة على ما هي Dart؟. للمقارنة مع تناول Dart داخل Flutter، انظر لغة Dart بعمق في مسار Flutter.
المشكلة: «خطأ المليار دولار»
القيمة null تعني «لا قيمة». المشكلة الكلاسيكية أنّك قد تحاول استخدام متغيّر تظنّه يحمل قيمة بينما هو null، فينهار البرنامج بخطأ وقت التشغيل. أطلق مبتكر المفهوم نفسه على هذا «خطأ المليار دولار» لكثرة الأعطال التي سبّبها عبر العقود.
الحلّ: غير قابل للإفراغ افتراضيًا
في Dart مع الأمان من القيم الفارغة (Sound Null Safety)، القاعدة الأساسية:
المتغيّرات لا يمكن أن تحمل
nullافتراضيًا، إلا إذا صرّحت بذلك صراحةً.
String name = 'Sara'; // لا يمكن أن يكون null أبدًا
// name = null; // خطأ في وقت الترجمة، لا في وقت التشغيل
الفائدة الكبرى: يمسك المُترجِم الخطأ قبل التشغيل، فتختفي مفاجآت الانهيار بسبب null في يد المستخدم.
الأدوات: ? و ! و late و required
-
?(قابل للإفراغ): يسمح للنوع بأن يكونnullصراحةً.String? nickname; // مسموح أن يكون null -
!(مؤكِّد عدم الإفراغ): تقول للمُترجِم «أنا واثق أنّ هذه القيمة ليست null هنا». استخدمه بحذر؛ إن أخطأت، ينهار البرنامج. -
late: يؤجّل تهيئة متغيّر غير قابل للإفراغ إلى ما بعد التصريح، مع وعدٍ بإسناد قيمة قبل الاستخدام. -
required: يجعل معاملًا مسمّى إلزاميًا في الدالّة أو الباني، فلا يُترك دون قيمة.
كيف يغيّر هذا طريقتك في الكتابة؟
بدل أن تنثر فحوص if (x != null) دفاعيًا في كل مكان، يجبرك النظام على التعامل مع احتمال الإفراغ عند مصدره. النتيجة كود أوضح نيّةً وأقلّ عرضةً للأعطال: يميّز القارئ فورًا أي القيم قد تكون فارغة وأيها مضمونة.
مقارنة سريعة
لغات كثيرة تجعل كل مرجع قابلًا للإفراغ ضمنيًا، فتترك الباب مفتوحًا لأخطاء null حتى وقت التشغيل. نهج Dart (وهو مشابه لِما في Kotlin) يقلب الافتراض: الأصل عدم الإفراغ، والإفراغ استثناء تصرّح به — فينتقل اكتشاف الخطأ من المستخدم إلى المُترجِم.
الخطوات التالية
بعد إتقان الأمان من القيم الفارغة، ستنتقل إلى المستقبلات (Futures) والبرمجة غير المتزامنة، ثم الأصناف والبواني ومعالجة الأخطاء. راجع الأساس في ما هي Dart؟.