Rust / المتقدم / الدرس 18
تصميم الواجهات ومشروع تقارير ختامي
ادمج الملكية والأخطاء والوحدات والقياس في واجهة تقارير صغيرة تظهر وعود الفحص والتوافق للمستهلك.
في هذه الصفحة
أهداف الدرس
- استخدام نوع غلاف مفحوص لتضييق المجال المقبول.
- فصل تحليل الحدود والحساب الخالص والعرض.
- مراجعة التوافق والحد الأدنى للأدوات وضمانات الفشل.
تحديد الملكية والفشل قبل الصياغة
توضح الواجهة ملكية المدخلات والمخرجات والاحتفاظ بالاستعارات والفشل. تناسب الشريحة تقريرًا فوريًا مقروءًا، وتحتاج المهمة المنتظرة بيانات مملوكة أو مالكًا محتفظًا به. أعد ملخصًا مملوكًا ليعيش بعد الإدخال. لا تضف Clone أو Send أو static لمجرد راحة تنفيذ واحد؛ فكل قيد عام يحد المستدعين. حدّد حجم الإدخال والحساب والترتيب والأخطاء قبل التمثيل ليحفظ التحسين العقد.
جعل العد الصالح نوعًا مستقلًا
يغلف newtype التمثيل ويخفي الإنشاء غير المفحوص. يسمح المثال بالعد حتى ألف ويعرض قارئًا. يبقى الحقل خاصًا في المكتبة لمنع المستدعي الخارجي من إنشاء قيمة فاسدة بالواجهة العادية. تحفظ Result سبب الرفض. لا يحدد الغلاف كل حساب أو تسلسل تلقائيًا؛ ويجب أن تقرر العمليات هل يبقى الجمع في المجال أم ينتمي إلى نوع تجميع مختلف.
mod counts {
pub struct Count(u32);
impl Count {
pub fn new(value: u32) -> Result<Self, &'static str> {
if value > 1000 { Err("count too large") } else { Ok(Self(value)) }
}
pub fn get(&self) -> u32 { self.0 }
}
}
fn main() {
let count = counts::Count::new(42).expect("known valid input");
println!("{} {}", count.get(), counts::Count::new(1001).is_err());
}
42 true
تصبح اثنتان وأربعون Count صالحة، وتُرفض ألف وواحد قبل إنشاء النوع.
فصل حساب التقرير عن الإدخال والإخراج
يستقبل المثال شريحة ويعيد صفًا مملوكًا بالعدد والمجموع. تتوقف try_fold عند أول فيض وتعيد None دون تعديل الإدخال. قد تكون بنية ملخص وخطأ منظم أوضح في واجهة فعلية. يطبع المثال نتيجة عادية وفيضًا مفحوصًا دون الاعتماد على إعداد التصحيح. يعطي الفراغ صفر سجلات ومجموع صفر. يستطيع محول الطرفية التحليل والعرض دون وضع عملياتها داخل الحساب الخالص.
fn report(records: &[u32]) -> Option<(usize, u32)> {
let total = records.iter().try_fold(0u32, |sum, value| sum.checked_add(*value))?;
Some((records.len(), total))
}
fn main() {
let (count, total) = report(&[2, 4, 6]).expect("small total");
println!("{count} {total}");
println!("{:?}", report(&[u32::MAX, 1]));
}
3 12
None
مجموع ثلاثة سجلات اثنا عشر، ولا يتسع u32 للمجموع الثاني فتكون قيمة الفشل الصريحة None.
التغيير العام يؤثر في المستهلكين أيضًا
الإصدارات الدلالية سياسة للمستهلك لا ضمان بناء محلي. قد تكسر التواقيع والقيود والحقول وشمول التعداد المستدعين. قد تستلزم إضافة بديل تحديث match ما لم تسمح الواجهة مسبقًا بمعالجة غير شاملة. يستبعد رفع rust-version أدوات أقدم فيجب قصده. وثّق الإصدار والميزات وpanic والتخصيص وثبات الأخطاء. أخفِ المساعدات كي لا يصير التنفيذ التزام توافق عرضيًا. توفر اختبارات التكامل والتوثيق رؤية المستهلك.
تسليم نظام صغير قابل للمراجعة
ابنِ مكتبة للأنواع المفحوصة والتقرير وبرنامجًا للإدخال الاصطناعي والعرض. ارفض السطور المشوهة بأخطاء منظمة وسياق وحدود عدد وترتيب حتمي. اختبر الفراغ والحدود والتكرار والفيض وثبات الإدخال عند الفشل. حدّد الملكية والضم والإغلاق قبل الموازاة، واعتماد البيئة والإلغاء قبل async. قِس حمل إصدار ممثلًا بعد نجاح الصحة واحتفظ بالقياس مع إصدار المصدر. ينبغي أن يفهم مطور آخر الالتزامات دون قراءة كل التفاصيل.
الأخطاء الشائعة وإصلاحها
واجهة قراءة تستهلك كل سجل بلا حاجة.
- لماذا يحدث؟
- حددت راحة التنفيذ عقد الملكية.
- كيف تصلحه؟
- استعر شريحة إذا لم تحتفظ العملية بالبيانات.
- كيف تتجنب تكراره؟
- اختر الملكية وفق متطلبات العمر.
بديل تعداد جديد يكسر مطابقة المستهلك.
- لماذا يحدث؟
- كانت الشمولية جزءًا من العقد العام.
- كيف تصلحه؟
- خطط التوافق أو تصميمًا غير شامل موثقًا.
- كيف تتجنب تكراره؟
- راجع التغيير من شيفرة المستهلك.
تحسين يرفع الحد الأدنى للمترجم صمتًا.
- لماذا يحدث؟
- أُدخلت واجهة أحدث دون مراجعة الدعم.
- كيف تصلحه؟
- استخدم بديلًا مدعومًا أو حدّث rust-version عمدًا.
- كيف تتجنب تكراره؟
- افحص الأدوات الدنيا المعلنة ضمن الاختبارات.
اختبر فهمك
1. اذكر نتيجة report للشريحة الفارغة وصمّم نوع نتيجة أوضح لمكتبة يجب أن تشرح الفيض.
اعرض الحل المشروح
تعيد الدالة Some((0, 0)). قد تعيد الواجهة Result<Summary, ReportError> بحقلَي records وtotal وبديل Overflow. يفصل ذلك نجاح الفراغ عن فشل الحساب دون تفسير مواضع صف أو غياب. اختبر نجاح الفراغ وفئة الفيض.
2. يريد مستدعٍ وضع التقرير في طابور ثم إسقاط متجه الإدخال. فسّر تغيير الواجهة المستعارة المطلوبة.
اعرض الحل المشروح
يجب أن تملك المهمة السجلات أو تحتفظ بمالك مشترك ثابت حتى الإكمال. اقبل Vec بالقيمة وانقلها للمهمة أو وثّق مشاركة المالك. لا توفر الشريحة العمر وحدها. أدرج حدود الطابور والإلغاء وتسليم الخطأ والإغلاق في العقد قبل مقارنة الأداء.
أهم ما تعلمته
- الملكية والأخطاء والتوافق التزامات عامة.
- افصل الفحص والحساب الخالص والعرض.
- ادمج القياس بعد حفظ الصحة.