محتويات الدورة
Dart
الأساسيات: القيم والغياب والمجموعات والكائنات الصالحة
العقود: الأنماط والواجهات العامة والنتائج غير المتزامنة
التكامل: الأهداف والموارد والتحقق والأدلة

Dart / الأساسيات: القيم والغياب والمجموعات والكائنات الصالحة / الدرس 1

فهم قيم Dart وأنواعها والفرق بين final وconst

اقرأ نقطة دخول برنامج Dart صغير، وميّز الأنواع المستنتجة وإعادة الإسناد والكائنات الثابتة والعمليات العددية وافتراضات المنصة.

وقت القراءة التقريبي: 5 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • اشرح لماذا لا تعني var النوع dynamic، ولماذا لا تمنح final ثباتا عميقا للكائن.
  • توقّع القسمة الصحيحة المبتورة والقسمة العادية، مع التصريح بأن الأمثلة غير منفذة.

ابدأ بحد تنفيذ صريح واحد

يملك تطبيق Dart نقطة دخول main معرّفة على المستوى الأعلى. تحوّل print معاملها إلى نص وتكتب سطرا عبر آلية إخراج المنصة. تستخدم الدورة برامج مصدر صغيرة ببيانات اصطناعية لمعالجة دفعات، ولا تفترض Flutter أو متصفحا أو إطار خادم. تدعم Dart أهداف ترجمة ومنصات مختلفة، ولذلك قد لا توجد مكتبة متاحة على الآلة الافتراضية الأصلية في شيفرة المتصفح. لم يتوفر الأمر dart أثناء التأليف. لذلك يمثل كل مخرج في الدورة توقعا مبنيا على تحليل الشيفرة، وتبقى جميع كتل المصدر runnable:false بدلا من ادعاء تنفيذ لم يحدث.

يبقى لتصريح var نوع ساكن محدد

تطلب var من Dart استنتاج النوع من المهيئ، ولا تعطل الفحص الساكن. يظل المتغير المهيأ بعدد صحيح خاضعا للنوع العددي المستنتج، ولا يقبل نصا اعتباطيا لاحقا. يمكن لـObject? صريحة حمل قيم مختلفة الأنواع ومنها null، لكن يجب تضييق النوع قبل استعمال عمليات تخص نوعا فرعيا. أما dynamic فتؤجل كثيرا من الفحوص إلى وقت التشغيل، وقد تنقل خطأ بسيطا بعيدا عن مصدره. فضّل الاستنتاج عندما يوضح المهيئ النوع، واستخدم النوع الصريح لتوضيح عقد عام أو قيمة ملتبسة.

dart حساب دفعة محلي بأنواع مستنتجة وصريحة
void main() {
  final batchSize = 7;
  var processed = 2;
  processed += 1;
  final int remaining = batchSize - processed;
  print('remaining=$remaining');
  print('processed=$processed');
}
الناتج المتوقع
remaining=4
processed=3

المخرج المتوقع remaining=4 ثم processed=3. يُسند batchSize مرة واحدة، بينما يعاد إسناد processed عمدا. لم يُستدع مترجم Dart أو بيئة تشغيلها.

افصل الإسناد الواحد عن الكائن الثابت

تمنع final إعادة الإسناد بعد التهيئة، لكنها لا تجمّد الكائن المشار إليه. قد تسمح قائمة final بإضافة عناصر إذا كان تنفيذها الفعلي قابلا للتعديل. تتطلب const قيمة ثابتة وقت الترجمة، وتنشئ كائنا ثابتا حيث تدعم اللغة ذلك. لا يمكن تعديل قائمة const عبر مرجع آخر. لا يعني هذا أن كل كائن يمكن الوصول إليه من final اعتباطية ثابت أيضا، ولا تحل const محل قاعدة تحقق في المجال. حدّد هل يحتاج البرنامج ربطا مستقرا أو حاوية غير قابلة للتعديل أو نموذجا قيميا عميقا، قبل اختيار الصياغة.

اختر دلالة الحساب قبل تنسيق المخرج

للمدخلات الصحيحة العادية المحدودة، تجري / قسمة بنتيجة double، بينما تجري ~/ قسمة مبتورة باتجاه الصفر. لا تنقل افتراضات القسمة الصحيحة من لغة أخرى. تمثل num نوعا أعلى مشتركا لـint وdouble، ولا تعد بأن كل عملية تحفظ النوع الفرعي الأصلي. قد تختلف حدود التمثيل وسلوك الأعداد الصحيحة الدقيقة بين أهداف ترجمة Dart، لذلك يحتاج الاعتماد على أعداد كبيرة جدا عقدا خاصا بالهدف. ولا يثبت عرض كسر عشري دقة الحساب العشري. يقتصر المثال على قيم صغيرة يسهل استنتاج نتائجها المعلنة.

dart قائمة final قابلة للتعديل وعملتا قسمة
void main() {
  final labels = <String>['A'];
  labels.add('B');
  const fixedLabels = <String>['A'];
  print(labels.length);
  print(fixedLabels.length);
  print(7 ~/ 2);
  print(7 / 2);
}
الناتج المتوقع
2
1
3
3.5

الأسطر المتوقعة هي 2 ثم 1 ثم 3 ثم 3.5. يسمح ربط final بتعديل القائمة، بينما fixedLabels قائمة ثابتة لا يحاول البرنامج تعديلها. هذه نتائج متوقعة لمصدر غير منفذ.

افصل العرض عن معنى القيمة المخزنة

تُدرج القوالب النصية متغيرا باسم مسبوق بالدولار أو تعبيرا بين أقواس معقوفة. لا يغير الإدراج الحساب الأساسي ولا يتحقق من معرف الدفعة. لطول String معنى مرتبط بتمثيل اللغة، فلا تفترض أنه يعد كل محرف يدركه المستخدم في جميع أنظمة الكتابة. أظهر الوحدات في الأسماء، واختر التحويلات الصريحة عند الحدود، ولا تستخدم نص العرض رمزا آليا مستقرا. تجعل المدخلات الحتمية الصغيرة هذه الفروق واضحة قبل إضافة إدخال تفاعلي أو إدخال وإخراج للمنصة أو عمل غير متزامن ذي حالات فشل إضافية.

الأخطاء الشائعة وإصلاحها

يُسنَد نص لاحقا إلى var مهيأة بعدد.

لماذا يحدث؟
اختلط استنتاج النوع بتأجيل فحوص النوع إلى وقت التشغيل.
كيف تصلحه؟
حافظ على نوع ساكن متماسك أو نمذج القيم البديلة صراحة.
كيف تتجنب تكراره؟
راجع الأنواع المستنتجة عند الحدود المهمة بدلا من الاعتماد على الكلمة وحدها.

تتغير قائمة final بعد تمريرها إلى دالة أخرى.

لماذا يحدث؟
اختلط ثبات الربط بثبات محتويات الكائن.
كيف تصلحه؟
اختر نسخة أو تمثيلا غير قابل للتعديل مناسبين، وحدّد الملكية.
كيف تتجنب تكراره؟
اختبر التعديل عبر مراجع أخرى قبل الوعد بلقطة مستقرة.

تعيد القسمة كسرا بينما كان المطلوب عددا صحيحا.

لماذا يحدث؟
استخدم البرنامج / بدلا من عملية القسمة المبتورة المقصودة.
كيف تصلحه؟
اختر ~/ فقط عندما يطابق البتر قاعدة المجال.
كيف تتجنب تكراره؟
أدرج أمثلة لا تقبل القسمة الكاملة وأخرى سالبة عند تحديد التقريب.

اختبر فهمك

1. توقّع 9 / 2 و9 ~/ 2. وهل يجعل تنسيق ناتج الأولى كعدد صحيح الخوارزمية مكافئة للثانية؟

اعرض الحل المشروح

النتيجتان 4.5 و4. لا يغير التنسيق سوى العرض، وقد يضيف سياسة تقريب مستقلة؛ ولا يعيد تعريف العملية التي أنتجت القيمة. قرّر هل الصحيح هو البتر أو التقريب أو حفظ الكسر قبل التنسيق. ينبغي أن توثّق قاعدة حجم الدفعة كيفية التعامل مع الباقي صراحة.

2. هل يمكن تهيئة final وقت التشغيل، وهل يمكن أن تعتمد const على استجابة لا تتوفر إلا وقت التشغيل؟

اعرض الحل المشروح

يمكن أن تتلقى final قيمة وقت التشغيل ثم تبقى مسندة مرة واحدة. أما const فيجب أن تحقق قواعد الثبات وقت الترجمة، فلا تصلح استجابة تشغيل اعتباطية مهيئا لها. لا يتحقق أي اختيار من الاستجابة ولا يحدد ملكية كائناتها القابلة للتعديل؛ وتبقى هذه مسؤوليات حد الاستقبال.

أهم ما تعلمته

  • استنتاج النوع وإعادة الإسناد وإنشاء الثوابت وتعديل الكائن قرارات مختلفة.
  • تعتمد النتائج العددية على عمليات Dart وهدف الترجمة المعلن.

المراجع الرسمية