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

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

اختيار المجموعات وفهم عمل Iterable الكسول

استخدم القوائم والمجموعات والخرائط المنمطة وعناصر بناء المجموعات والتحويل الكسول واللقطات الصريحة، دون خلط الواجهة بالثبات.

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

أهداف الدرس

  • اختر دلالات الترتيب والفريدة والبحث بقصد.
  • اشرح وقت تقييم map وwhere، وما الذي تحميه نسخة غير قابلة للتعديل فعلا.

شكل المجموعة جزء من عقد البيانات

تحفظ List ترتيبا مفهرسا وتسمح بالتكرار. تمثل Set العناصر الفريدة وفقا لعقد مساواتها. تربط Map مفاتيح بقيم وتعيد من البحث العادي نتيجة قابلة للخلو لاحتمال غياب المفتاح. يمثل {} الفارغ خريطة ما لم يحدد سياق النوع خلاف ذلك؛ بينما يعلن <String>{} مجموعة نصوص صراحة. اختر المجموعة من المعنى لا علامات الصياغة. قد تكون تسميات العينات المكررة خطأ أو ملاحظات مستقلة، فيفقد تحويلها إلى Set بيانات مشروعة. ويختلف استبدال قيمة مفتاح عن تجميع قيم عدة تحته.

قد تؤجل تحويلات Iterable في Dart العمل

تعيد map وwhere على Iterable عادية منظورا كسولا للحساب بدلا من قوائم مكتملة متحمسة. يطلب مستهلك نهائي مثل toList العناصر وينفذ العمل. قد يكرر المرور اللاحق النداءات ويرى تغييرات المصدر المعدل، فتجنب وضع آثار مهمة داخل التحويل. يعد المثال النداءات لكشف وقتها، لا للتوصية بالتعديل داخل map. يجب على القادم من لغة ذات تحويل قوائم متحمس فحص عقد Dart الفعلي، لا افتراض تطابق استراتيجية التقييم لمجرد تشابه الاسم.

dart ملاحظة التقييم الكسول لـmap
void main() {
  var visited = 0;
  final mapped = <int>[1, 2, 3].map((value) {
    visited += 1;
    return value * 2;
  });
  print(visited);
  print(mapped.toList());
  print(visited);
}
الناتج المتوقع
0
[2, 4, 6]
3

المخرج المتوقع 0 ثم [2, 4, 6] ثم 3. لا يستدعي إنشاء mapped الدالة، وتكرّر toList على العناصر الثلاثة. لم يُنفّذ المصدر.

ابن النتائج دون إخفاء تعديل أثناء المرور

قد تتضمن صيغ المجموعات عناصر نشر وشروط if وتكرار for. تبني هذه الصيغ نتيجة مباشرة مع وضوح الاختيار والترتيب. ينسخ النشر مراجع العناصر التي يمر عليها إلى الحاوية الجديدة، ولا يستنسخها بعمق. يعالج النشر الواعي بالخلو مصدرا قد يكون null وفق عقده، لا عناصر مشوهة داخله. أبق التعبيرات مقروءة وتجنب تعشيق التحكم في البناء إذا أوضحت دالة مساعدة السياسة. لا يفيد القصر إلا إذا بقي معنى البيانات مفهوما.

تظل عناصر القائمة غير القابلة للتعديل ذات دلالة سطحية

تتضمن واجهة List في Dart عمليات تعديل؛ فلا يمثل النوع وحده وعدا بالقراءة فقط. ترفض القائمة غير القابلة للتعديل تغيير الحاوية، وقد يختلف ارتباط المنظور واللقطة المنسوخة بتغيرات المصدر. تنشئ List.unmodifiable قائمة غير قابلة للتعديل بمراجع العناصر المعطاة. قد تتغير كائنات العناصر المعدلة داخليا. يستخدم المثال نصوصا لعزل ملكية الحاوية؛ فلا تؤثر إضافات المصدر اللاحقة في اللقطة. اختر الواجهة التي تطابق دلالات نسخها أو منظورها الوعد، ولا تصف النسخ السطحي بأنه ثبات عميق.

dart مرجع مشترك ولقطة واستبدال قيمة خريطة
void main() {
  final source = <String>['sample-A'];
  final alias = source;
  final snapshot = List<String>.unmodifiable(source);
  source.add('sample-B');
  print(alias.length);
  print(snapshot.length);
  final counts = <String, int>{'A': 1};
  counts['A'] = 2;
  print(counts['A']);
  print(counts['missing'] ?? -1);
}
الناتج المتوقع
2
1
2
-1

المخرج المتوقع 2 ثم 1 ثم 2 ثم -1. يستبدل تحديث A قيمته، ويختار البحث الغائب البديل. لا يحاول البرنامج تعديل snapshot ولم يُنفّذ.

أظهر حجم النتيجة وسلوك الفراغ

قد يستهلك المسار الكسول عملا غير محدود إذا طلبت العملية النهائية كل شيء. يحتاج فرز النتائج الكبيرة وتجسيدها ذاكرة ولو كانت المراحل السابقة كسولة. تحتاج first ونحوها سياسة للفراغ؛ فلا تخترع معرفا لإخفاء الغياب. وإذا سمحت الخريطة بقيم null فإن containsKey تميز الموجودة من المفتاح الغائب. راجع مساواة المجموعة مستقلة عن مساواة عناصرها وأبق مفاتيح التجزئة ثابتة. تتبع هذه الاختيارات عقد البيانات، لا قاعدة عامة بأن الكسل أو منع التعديل يحلان الصحة دائما.

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

يبدو أن دالة map لا تعمل.

لماذا يحدث؟
لم يُستهلك Iterable الناتج الذي يؤجل العمل.
كيف تصلحه؟
استهلكه بقصد أو نفّذ عملية متحمسة صريحة عند الحاجة.
كيف تتجنب تكراره؟
أبعد الآثار عن التحويل الكسول حتى لا يفاجئ وقتها القارئ.

تحتوي قائمة غير قابلة للتعديل كائنات ما زالت تتغير.

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

تختفي ملاحظات مكررة بعد التحويل إلى Set.

لماذا يحدث؟
فُرضت الفريدة دون فحص معنى التكرار.
كيف تصلحه؟
احفظ القائمة أو اجمع الملاحظات وفقا للمجال.
كيف تتجنب تكراره؟
حدّد معالجة التكرار عند حد الإدخال.

اختبر فهمك

1. هل يعيد المرور مرتين على Iterable محولة كسولا استخدام قائمة نتائج مخزنة واحدة دائما؟

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

لا. قد تستدعي Iterable الكسولة المعتادة التحويل مجددا لكل مرور، وقد تؤثر تغييرات المصدر. جسّد لقطة مقصودة عندما يلزم إعادة الاستخدام والثبات، مع مراعاة مراجع العناصر السطحية. يحدد عقد الواجهة، لا وجود final على المتغير، هل المخزن وصف حساب أم بيانات.

2. لماذا لا تكفي List.unmodifiable لجعل قائمة كائنات نماذج قابلة للتعديل ثابتة بعمق؟

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

تمنع تغيير الحاوية لكنها تحتفظ بمراجع كائنات العناصر. قد يعدّل مالك آخر تلك الكائنات فيتغير ما يراه القارئ. استخدم عناصر قيمية ثابتة أو نسخا محددا بعناية أو ملكية حصرية عند الحاجة. افحص الحالة المتداخلة الفعلية ولا تستنتج ضمانا أقوى من اسم المنشئ.

أهم ما تعلمته

  • يغير كسل Iterable في Dart وقت حدوث العمل والآثار.
  • الترتيب والفريدة واللقطات وملكية العناصر عقود منفصلة.

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