Rust / الأساسي / الدرس 5
البنى والتعدادات ومطابقة الأنماط
نمذج البيانات المرتبطة والحالات المحدودة لتحفظ العمليات خصائصها وتغطي match البدائل المطلوبة.
في هذه الصفحة
أهداف الدرس
- تعريف الحقول المسماة والأساليب وحدود الإنشاء.
- تمثيل الحالات المتنافية بحمولات enum.
- مطابقة البيانات المستعارة دون نقل غير مقصود.
تسمية الحالات الصالحة أولًا
تجمع struct حقول قيمة واحدة وتعرّف impl الدوال المرتبطة والأساليب. تصف الخاصية الثابتة العلاقة الصالحة بين الحقول، كعدم سلبية المخزون أو إيجابية الأبعاد. اختر العمليات العامة حول القواعد بدل كشف كل حقل للتعديل. لا يفرض أمان ذاكرة Rust خصائص العمل تلقائيًا. تقلل الحقول الخاصة والإنشاء المفحوص الشيفرة القادرة على تغيير التمثيل فتسهل مراجعة الالتزام واختباره.
الأسلوب يعلن متطلبات وصوله
يراقب أسلوب &self باستعارة مشتركة، ويطلب &mut self وصولًا حصريًا للتعديل، ويستهلك self القيمة. تستخدم المنشئات المرتبطة اسم new غالبًا دون معنى لغوي خاص له. يفحص مثال المخزون الطلب كاملًا قبل الطرح؛ فلا يصل طلب مفرط إلى طرح غير ذي إشارة. تبلغ bool عن القبول دون إنشاء حالة وسطية فاسدة. اختبر الكمية الباقية مع النتيجة لأن الرفض يجب أن يترك المخزون ثابتًا.
struct Stock { quantity: u32 }
impl Stock {
fn withdraw(&mut self, amount: u32) -> bool {
if amount > self.quantity { return false; }
self.quantity -= amount;
true
}
}
fn main() {
let mut stock = Stock { quantity: 10 };
let first = stock.withdraw(3);
let second = stock.withdraw(8);
println!("{first} {second} {}", stock.quantity);
}
true false 7
تترك ثلاث وحدات سبعًا، ويُرفض طلب الثماني فتبقى سبع دون نقصان غير ذي إشارة.
استخدام بدائل enum للحالات
يمثل enum بديلًا نشطًا واحدًا وتحمل بدائله أنواعًا مختلفة. يتجنب ذلك أعلامًا متوازية تسمح بتناقض مثل جاهز وفاشل معًا. يمثل Option<T> وجود قيمة أو غيابها صراحة بدل عدد سحري. يستطيع تعداد المجال ربط الوحدات بـReady والرسالة بـFailed فقط. يسجل الإنشاء البيانات التابعة لكل حالة، ويبقى فحص قيم الحمولة مسؤولية التطبيق.
معالجة بنية كل حالة
تختار match ذراعًا بالنمط وتغطي النوع كاملًا. يستعير المثال &Job فلا تستهلك المطابقة رسالة الخطأ المملوكة. يتيح ربط النمط الحمولة النشطة وتنتج الأذرع String. قد يفيد الذراع العام لكنه يخفي بدائل مستقبلية تحتاج سياسة جديدة. استخدم البدائل الصريحة حين تهم المراجعة الشاملة. تلائم if let نمطًا واحدًا مهمًا وتوضح match عملية شاملة تعتمد على الحالة.
enum Job { Ready(u32), Paused, Failed(String) }
fn describe(job: &Job) -> String {
match job {
Job::Ready(units) => format!("ready: {units}"),
Job::Paused => String::from("paused"),
Job::Failed(reason) => format!("failed: {reason}"),
}
}
fn main() {
for job in [Job::Ready(3), Job::Paused, Job::Failed(String::from("disk"))] {
println!("{}", describe(&job));
}
}
ready: 3
paused
failed: disk
تختار كل حالة ذراعًا واحدًا. تملك الأوصاف النص المعاد ولا يُستعار التعداد إلا مؤقتًا.
الأنماط تشارك في الملكية أيضًا
قد ينقل تفكيك قيمة مملوكة حقولًا ليست Copy، بينما تنشئ مطابقة مرجع ارتباطات مستعارة عادة وفق تسهيل المطابقة. افهم نوع القيمة قبل إضافة clone أو فك المرجع. تضيف الحراس شروطًا بعد المطابقة ولا تغني عن معالجة الباقي. أبقِ فحص الحمولة في المنشئات العامة. تستطيع الوحدات إخفاء التمثيل وإظهار انتقالات الحالة لتغيير التنفيذ دون تغيير المستدعين. يقلل النموذج القوي التناقض ويظل محتاجًا اختبارات للانتقالات والرفض وسياسة التنسيق.
الأخطاء الشائعة وإصلاحها
إغفال بديل في match.
- لماذا يحدث؟
- العملية لا تغطي مجال التعداد كاملًا.
- كيف تصلحه؟
- أضف الذراع المطلوب بسياسة صريحة.
- كيف تتجنب تكراره؟
- فضّل البدائل الشاملة عند تطور الحالات.
المطابقة تستهلك رسالة خطأ دون قصد.
- لماذا يحدث؟
- فُكك تعداد مملوك بالقيمة.
- كيف تصلحه؟
- طابق مرجعًا إذا كفت المراقبة.
- كيف تتجنب تكراره؟
- راجع ملكية القيمة قبل ربط الحمولة.
عملية مخزون تغيّر الحالة قبل الرفض.
- لماذا يحدث؟
- حدث الفحص بعد الحساب.
- كيف تصلحه؟
- افحص الانتقال قبل تغيير الحقول.
- كيف تتجنب تكراره؟
- اختبر النتيجة مع الحالة الناتجة.
اختبر فهمك
1. طبّق سحب صفر ثم عشرة ثم واحد على مخزون جديد من عشرة. اذكر النتائج والكمية النهائية.
اعرض الحل المشروح
ينجح الصفر وتبقى عشرة، وتنجح العشرة فيبقى صفر، ثم يفشل الواحد ويبقى صفر. النتائج true وtrue وfalse. لا يحدث طرح قبل الفحص فلا يلزم تمثيل مخزون سالب. اختبرها انتقالات منفصلة لا سطرًا نهائيًا فقط.
2. أضف Cancelled برسالة String إلى Job. فسّر تغيير describe وسبب إضعاف الذراع العام للمراجعة.
اعرض الحل المشروح
أضف Job::Cancelled(String) وذراعًا مستعارًا صريحًا يعيد وصف إلغاء منسقًا. يحدد المترجم الذراع الناقص في المطابقة الشاملة. قد يستوعب ذراع عام سابق الإلغاء بصمت دون سببه، فتفيد المعالجة الصريحة عندما تحتاج كل حالة سياسة عرض مقصودة.
أهم ما تعلمته
- نمذج البدائل بحمولات enum.
- افحص الانتقالات قبل التعديل.
- تعبّر الأنماط والأساليب عن الملكية والسلوك.