ملاحظةدقيقتا قراءة

متى نحتاج إلى subscript آمن في Swift؟

متى يكون إرجاع nil عند فهرس غير صالح مفيدًا، ومتى يخفي خطأ في الشيفرة؟ اختيار subscript آمن يعتمد على مصدر الفهرس وتكلفة فحصه.

عرض بصيغة Markdown

هذه إضافة شائعة في مشاريع Swift. تتيح الوصول إلى عنصر بالفهرس، وتعيد nil إذا كان خارج حدود المجموعة:

extension Collection {
  subscript(safe index: Index) -> Element? {
    indices.contains(index) ? self[index] : nil
  }
}
let names = ["John", "Mike"]

names[2]        // crash
names[safe: 2]  // nil

الوصول إلى فهرس خارج حدود المجموعة يوقف البرنامج. تعيد هذه الإضافة قيمة اختيارية (optional) بدلًا من ذلك، ويمكن التعامل معها باستخدام if let.

لكن هذا يغيّر طريقة اكتشاف الخطأ. عند كتابة names[2] لمصفوفة من عنصرين، تتوقف Swift عند موضع الوصول الخاطئ. تستطيع فحص الفهرس وقراءة stack trace لمعرفة كيف وصل التنفيذ إليه. أما مع [safe:] فقد تتجاهل الشيفرة قيمة nil وتستمر، ولا تلاحظ المشكلة إلا لاحقًا: صف فارغ في الواجهة، أو عنصر ناقص من النتيجة.

قبل استخدام الإضافة، اسأل عن مصدر الفهرس. إذا كنت تمر على indices للمجموعة نفسها، فأنت تعرف أنه صالح. وإذا حسبته من count، فتحقق من الحساب وحدود المجموعة. أما إذا جاء من مسار آخر، فقد تحتاج فعلًا إلى التعامل مع غياب العنصر:

  • فهرس مأخوذ من حمولة بيانات أو من رابط
  • اختيار حُفظ قبل إعادة التحميل واستُعمل بعدها
  • فهرس أعاده callback من إطار عمل لمجموعة عدّلتها بعده

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

انتبه أيضًا إلى تكلفة الفحص. في Array، تكون indices من نوع Range<Int>، ولذلك يعمل contains بتعقيد O(1). أما في المجموعات التي تستخدم Sequence.contains، فقد يتطلب الفحص المرور على الفهارس واحدًا واحدًا. تصبح قراءة مثل someString[safe: i] بتعقيد O(n)، رغم أن شكلها يوحي بوصول مباشر. حصر الإضافة في RandomAccessCollection يستبعد String، لكنه لا يجعل فحص contains ثابت التكلفة تلقائيًا في كل نوع مخصص؛ راجع تنفيذ المجموعة.

استخدمها عندما يكون الفهرس غير موثوق، وتعامل مع nil بوضوح. أما إذا كان الفهرس يفترض أن يكون صالحًا، فإخفاء الخطأ قد يصعّب العثور عليه.

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

المواضيع