العودة
خواطر Rust حول Parse, don't validate: تحويل التحقق إلى أنواع
SiTech AI Team2 წთ. საკითხავი

خواطر Rust حول Parse, don't validate: تحويل التحقق إلى أنواع

يعيد إيلي بندرِسكي طرح فكرة Parse, don't validate من أجل Rust: لا يكفي التحقق من شرط والثقة به، بل يجب تحويل البيانات إلى نوع لا يمكن خرق زمامته، مع أمثلة من NonEmpty و NonZero وrust-analyzer.

نشر إيلي بندرِسكي مقالًا جديدًا في مدونته يعود فيه إلى فكرة طرحتها أليكسيس كينغ في مقال عام 2019. يقول النص الأصلي، المكتوب لـ Haskell، إن الشيفرة لا ينبغي أن تتحقق من شرط ثم تثق به، بل يجب أن تحوّل البيانات إلى نوع يجعل خرق الخاصية المضمونة مستحيلًا. يطبّق بندرِسكي المنظور نفسه على Rust ويبحث عن أمثلة تعليمية في المكتبة القياسية للغة وفي مشاريع معروفة.

متجه لا يمكن أن يكون فارغًا

نقطة البداية هي Vec العادي ودالته first()، التي تعيد مرجعًا اختياريًا لأن المتجه قد لا يحتوي أي عنصر. في مثال بندرِسكي تقرأ دالة قائمة مجلدات الإعداد من متغير البيئة CONFIG_DIRS وترفض النتيجة الفارغة، ومع ذلك يضطر الكود المستدعي إلى كتابة فرع لحالة لن تحدث أبدًا. يشبّه الكاتب مثل هذه الثوابت بقنبلة موقوتة: المصرّف لا يفرضها، لذا قد تنكسر لاحقًا بصمت. الحل هو نوع مستقل، مثل NonEmpty من الحزمة nonempty، لا يملك أي باني لقيمة فارغة، وتعيد دالته first() مرجعًا عاديًا. إعادة Vec مُتحقَّق منه هي تحقق، أما إعادة NonEmpty فهي تحليل، إذا فُهم التحليل بمعناه الواسع: تحويل البيانات من صيغة إلى أخرى.

أنابيب الأوامر والمسارات والتحسين التدريجي

ثم ينتقل المقال إلى ما هو أبعد من الأمثلة التعليمية. في مشروع posixutils-rs، وهو إعادة كتابة لأدوات POSIX الأساسية بلغة Rust، تُخزَّن أوامر أنبوب الصدفة بنوع NonEmpty، لذا يحتوي أي أنبوب محلَّل على أمر واحد على الأقل، ولا يعيد المحلل None إلا عندما لا يوجد ما يُشغَّل. ولدى rust-analyzer نوع مستقل للمسار المطلق: تفشل عملية التحويل إذا لم يكن المسار مطلقًا، ويعتمد الكود اللاحق على النوع بدل إعادة فحص الشرط. يسمي بندرِسكي ذلك التحليل التدريجي: يُثبت المسار أولًا أنه UTF-8 صالح عبر حزمة camino، ثم يُثبت أنه مطلق.

الأعداد غير الصفرية و JSON

في مكتبة Rust القياسية نوع عام اسمه NonZero للأعداد غير المؤشرة المعروفة بأنها ليست صفرًا. تعيد دالة available_parallelism قيمة كهذه عند النجاح، أما القسمة على مقام من نوع NonZero فموثّقة كعملية لا يمكن أن تنهار. وهناك ميزة إضافية: الصفر نمط بتات غير صالح لهذا النوع، لذا يشغل NonZero الاختياري المساحة نفسها التي يشغلها عدد صحيح عادي. وتظهر الفكرة ذاتها في تحليل JSON: مع serde يمكن تعريف بنية إعداد بحيث يكون عدد العمال غير صفري والوضع تعدادًا من قيمتين، فتُفرض أنواع الحقول والقيم المسموح بها ومنع الصفر في خطوة واحدة. في اللغات الديناميكية تكون العملية يدوية أكثر: تعيد json.loads في Python قاموسًا وتترك التحقق للمستدعي، بينما تقترب مكتبات مثل Pydantic من نهج Rust لكنها ليست مستخدمة في كل مكان.

SSiTech

SiTech — تطوير ويب مدعوم بالذكاء الاصطناعي

نبني مواقع سريعة وعصرية وندمج الذكاء الاصطناعي في سير عمل الشركات. لديك مشروع أو سؤال؟ يسعدنا مساعدتك.