التكرار عبر Vec مع الفهرس في Rust: 4 طرق للمقارنة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

التكرار عبر Vec مع الفهرس في Rust: من المبتدئ إلى المحترف



تخيل: أنت تكتب بلغة Rust وتحتاج إلى المرور عبر عناصر المتجه، ولكن في نفس الوقت تريد معرفة ليس فقط القيمة، بل أيضًا موضعها. قد تبدو مهمة بسيطة، لكنها غالبًا ما تسبب حيرة للمبتدئين. أين هو for i in range(len(vec)) كما في Python؟ وماذا لو أردت تغيير العناصر؟ وأي طريقة أسرع؟



في هذه المقالة، سنستعرض جميع الطرق الشائعة للتكرار عبر Vec مع الفهرس في Rust، ونقارن أداءها، وسهولة قراءتها، وأمانها. ستعرف أي طريقة تختار في عام 2024 ولماذا enumerate ليست دائمًا الحل الأمثل.



لماذا هذا مهم؟

في Rust، لا يوجد for i in 0..vec.len() كطريقة صحيحة وحيدة. تقدم اللغة عدة نماذج: من المكررات الوظيفية إلى الحلقات منخفضة المستوى. فهم الفرق بينها هو مفتاح كتابة كود فعال ومتوافق مع أسلوب اللغة. هذا مهم بشكل خاص عند العمل مع المتجهات، حيث قد تحتاج إلى الفهرس لتعديل العناصر المجاورة أو تتبع الموضع في الخوارزمية.



الطريقة 1: الكلاسيكية — enumerate

الطريقة الأكثر شيوعًا والموصى بها. طريقة enumerate تغلف المكرر، مضيفة فهرسًا لكل عنصر:



let vec = vec!["a", "b", "c", "d"];for (index, value) in vec.iter().enumerate() {    println!("الموضع {}: {}", index, value);}


المزايا:

  • متوافقة مع أسلوب اللغة وسهلة القراءة
  • آمنة — لا يوجد خطر الخروج عن الحدود
  • تعمل مع أي مكرر، وليس فقط Vec

العيوب: لا يمكن تغيير عناصر المتجه مباشرة (تحتاج إلى iter_mut()).



الطريقة 2: عبر الفهارس — 0..vec.len()

النهج المألوف للجميع من C++ أو Python. نستخدم نطاقًا من الفهارس:



let mut vec = vec![10, 20, 30, 40];for i in 0..vec.len() {    vec[i] += i; // تغيير العنصر حسب الفهرس    println!("vec[{}] = {}", i, vec[i]);}


المزايا:

  • تحكم كامل في الفهرس والعنصر
  • يمكن تغيير العناصر عبر vec[i]
  • سهل الفهم للمبتدئين

العيوب: أبطأ من المكررات (فحص إضافي للحدود). يعتبره مجتمع Rust "غير متوافق مع أسلوب اللغة".



الطريقة 3: while مع عداد

الطريقة الأكثر "يدوية" التي قد تجدها في الكود القديم أو عند التحسين:



let vec = vec![1.0, 2.0, 3.0];let mut i = 0;while i < vec.len() {    println!("العنصر {}: {}", i, vec[i]);    i += 1;}


المزايا: أقصى مرونة (يمكن القفز عبر الفهارس، تغيير الخطوة).

العيوب: سهولة الخطأ في الشرط. غير موصى به بدون سبب وجيه.



الطريقة 4: zip مع نطاق

النهج الوظيفي عندما تحتاج إلى التكرار عبر متجهين بالتوازي مع الفهارس:



let names = vec!["Alice", "Bob", "Charlie"];let scores = vec![95, 87, 92];

for (i, (name, score)) in (0..).zip(names.iter()).zip(scores.iter()) { println!("{}: {} حصل على {} نقطة", i, name, score);}


المزايا: قوي للتكرار المتوازي. النطاق اللانهائي 0.. يُقطع تلقائيًا.

العيوب: قد يكون معقدًا في القراءة. مبالغ فيه للمهام البسيطة.



مقارنة الأداء

أجرينا اختبارات الأداء على متجه من 100,000 عنصر (تحسين --release):



المدونات

توصيات الكتب

الطريقةالوقت (نانو ثانية)السرعة النسبية
enumerate~12,0001.0x (المرجع)
0..len~15,0001.25x أبطأ