محتويات الدورة

Rust / الأساسي / الدرس 6

المجموعات والإدخال المفحوص

خزّن التسلسلات والقيم ذات المفاتيح بملكية، وميّز التحليل من فحص المجال، وتجنب الاعتماد على ترتيب اجتياز غير مضمون.

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

أهداف الدرس

  • استخدام Vec وHashMap وBTreeMap وفق العمليات المطلوبة.
  • فحص الفهارس وشرح الحجم والسعة.
  • تحليل الإدخال المشذب كاملًا وفرض مجال التطبيق.

الطول يعد القيم والسعة تصف التخزين المحجوز

تملك Vec<T> تسلسلًا متجاورًا ناميًا من قيم T. تعد len العناصر المهيأة وتصف capacity التخزين المتاح قبل نمو إضافي. لا تنشئ with_capacity أو reserve العناصر. تلحق push قيمة وتحتاج الفهرسة موضعًا صالحًا وقد تسبب panic خارجه. تعيد get قيمة Option للحدود غير المؤكدة. تمنع قواعد الاستعارة إبقاء مرجع عنصر عبر تعديل قد يبطل الوصول. استخدم الواجهة العامة بدل مؤشرات إلى السعة غير المستخدمة في التطبيقات العادية.

قراءة العناصر القائمة دون استهلاكها

يحجز المثال مساحة ويلحق درجة رابعة ويجمع عبر تكرار مشترك. تنتج iter مراجع مشتركة وتحول copied أعداد Copy إلى قيم للجمع. يختار نوع u32 الصريح نوع المجمّع. تبقى القيم قابلة للتمثيل، ويلزم اختيار سياسة فيض للتجميع الفعلي. يبقى المتجه مملوكًا وصالحًا بعد التكرار. لا تُطبع السعة لأن مقدارها الدقيق ليس ضمن العقد. لا تلغي سلسلة مكررات مختصرة التزامات المجال العددي.

rust أربعة عناصر مملوكة وجمع مستعار
fn main() {
    let mut scores = Vec::with_capacity(8);
    scores.extend([2u32, 4, 6]);
    scores.push(8);
    let total: u32 = scores.iter().copied().sum();
    println!("{} {total}", scores.len());
}
الناتج المتوقع
4 20

يضم المتجه أربعة عناصر مجموعها عشرون، ولا يستهلك الجمع عبر iter مالكه.

اختيار البحث والترتيب بوعي

تخزن HashMap روابط مفاتيح وقيم ببحث فعال متوقع، ولا تضمن ترتيب تقارير ثابتًا. تتيح BTreeMap اجتيازًا مرتبًا بمفاضلات تخزين وتعقيد مختلفة. لا تعد بترتيب معين لطباعة HashMap كاملة. تستعير get القيمة، وقد تستبدل insert قيمة، وتتيح entry التحديث أو الإدخال مباشرة. تملك الخريطة مفاتيح String العادية ما لم تصمم مفاتيح مستعارة بأعمار. اختر تخزينًا مرتبًا أو افرز قائمة مفاتيح للتقارير.

التحليل أولًا ثم فحص المجال

يمكن قراءة الطرفية إلى String عبر read_line مع معالجة نتيجة الإدخال والإخراج. يستخدم الدرس سطرًا اصطناعيًا لناتج حتمي. تطبق trim سياسة مسافات مقصودة وتحاول parse تحويل النص كاملًا وتفرض الحراسة الصفر إلى المئة. يبقى تحليل مئتين ناجحًا لكن مخالفًا للمجال، ولا تصح لاحقة مشوهة لمجرد بدايتها بأرقام. ميّز فشل الإدخال والتحليل ورفض التطبيق إذا احتاجت الاستعادة إلى سياسات مختلفة.

rust حساب بإدخال مفحوص كامل
fn main() {
    let line = " 12 ";
    match line.trim().parse::<u32>() {
        Ok(count) if count <= 100 => println!("accepted {count}"),
        Ok(_) => println!("out of range"),
        Err(_) => println!("invalid integer"),
    }
}
الناتج المتوقع
accepted 12

تُحذف المسافات صراحة وتُحلل اثنا عشر كـu32 ثم تقبلها حراسة المجال.

فحص الحجم والقيمة معًا

قد يستهلك الإدخال غير الموثوق ذاكرة كبيرة رغم أمان العناصر. حدّ عدد السجلات وأحجام السطور بدل جمع مصدر غير محدود. افحص الفهارس واستخدم get للغياب المتوقع. قرر هل تستبدل المفاتيح المكررة القيم أو تجمعها أو تُرفض. عند إعادة القراءة امسح المخزن أو استبدله كي لا يلحق النص القديم بالخطأ. اختبر الفراغ وغياب المفاتيح والتكرار والسطور المشوهة والحد الأقصى. هذه قواعد منتج لا يستنتجها فاحص الأنواع.

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

فهرسة متجه محجوز السعة قبل وجود عناصر.

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

تغير ترتيب مفاتيح تقرير بين التشغيلات.

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

إدخال متكرر يتضمن السطر السابق.

لماذا يحدث؟
ألحقت read_line بمخزن String لم يُمسح.
كيف تصلحه؟
امسح المخزن قبل كل قراءة جديدة.
كيف تتجنب تكراره؟
اجعل إعادة استخدام المخزن ضمن عقد الحلقة.

اختبر فهمك

1. توقع مثال الإدخال مع "101" و"12x" و"-1" وطبقة رفض كل منها.

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

تُحلل 101 كـu32 وتطبع out of range. تفشل 12x في التحليل الكامل فتطبع invalid integer، ويفشل -1 في التحويل غير ذي الإشارة ويطبعها أيضًا. تزيل trim المسافات المحيطة فقط ولا تحذف لاحقة أو تجعل السالب عددًا غير سالب.

2. عد red وblue وred في خريطة وأنتج تقريرًا أبجديًا حتميًا. اذكر العدّ واختيار الحاوية.

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

استخدم BTreeMap<String, u32> وزد قيمة entry(color).or_insert(0) بسياسة فيض مناسبة للمدخلات الكبيرة. العد blue واحد وred اثنان ويأتي blue أولًا بالاجتياز المرتب. تستطيع HashMap حفظ العد نفسه، ولا يحدد اجتيازها المباشر التقرير المتوقع.

أهم ما تعلمته

  • يصف الطول والسعة موردين مختلفين.
  • اختر سياسات صريحة للإدخال والتكرار والترتيب.
  • تحتاج المجموعات الآمنة حدودًا للمجال والموارد.

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