شرائح Vec<T> في Rust: كيف تحصل عليها دون أن تصاب بالصداع في 2025

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

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

ابدأ الدورة

شرائح Vec<T> في Rust: كيف تعمل ولماذا تحتاجها؟

\n\n

إذا كنت قد كتبت بلغة Rust من قبل وتساءلت "How do I get a slice of a Vec<T> in Rust?" — فأنت لست وحدك. هذا أحد أكثر الأسئلة شيوعًا على Stack Overflow، وقد حصد آلاف المشاهدات. وليس من دون سبب: العمل مع المتجهات وشرائحها هو مهارة أساسية، لا يمكن تصور أي مشروع جاد في Rust بدونها.

\n\n

في هذه المقالة، لن نعرض فقط كيفية الحصول على شريحة. بل سنستعرض أفضل الممارسات لعام 2025، ونتعلم كيفية تجنب الأخطاء الشائعة، ونفهم لماذا تجعلنا Rust نفكر كثيرًا في الاقتراض. هيا بنا!

\n\n

ما هي الشريحة (slice) في Rust؟

\n\n

قبل أن نحصل على شريحة، دعنا نفهم ما هي. الشريحة هي مرجع لتسلسل متصل من العناصر في الذاكرة. في Rust، يُرمز للشريحة بـ &[T]. إنها بنية بيانات غير مالكة — فهي فقط "تنظر" إلى جزء من البيانات التي يملكها شخص آخر (مثل متجه أو مصفوفة).

\n\n

الميزة الرئيسية للشرائح هي الأمان. يضمن مترجم Rust أنك لن تتجاوز حدود الذاكرة، ونظام الاقتراض لن يسمح لك بتعديل البيانات أثناء وجود مراجع نشطة عليها.

\n\n

لماذا لا تستخدم المتجه مباشرة؟

\n\n

المتجه (Vec<T>) هو بنية مالكة. إذا مررته إلى دالة، فإما أن تنقله (وتفقد الوصول إليه) أو تمرر مرجعًا. تمنحك الشرائح المرونة: يمكنك تمرير جزء فقط من البيانات دون نسخها أو فقدان السيطرة على المتجه الأصلي.

\n\n

على سبيل المثال، تعمل مع مجموعة بيانات كبيرة وتريد تمرير جزء منها إلى دالة للتحليل. الشريحة هي الأداة المثالية: فهي خفيفة (كلمتان فقط: مؤشر وطول) وآمنة.

\n\n

الطرق الرئيسية للحصول على شريحة من Vec<T>

\n\n

دعنا ننتقل إلى التطبيق العملي. هناك عدة طرق للحصول على شريحة من متجه. سنستعرض الأكثر شيوعًا وملاءمة.

\n\n

1. عامل الترقيم: &vec[start..end]

\n\n

الطريقة الأكثر مباشرة هي استخدام عامل النطاق ..:

\n\n
let vec = vec![1, 2, 3, 4, 5];\nlet slice: &[i32] = &vec[1..4]; // شريحة من الفهرس 1 إلى 4 (بدون تضمين 4)\nprintln!("{:?}", slice); // [2, 3, 4]
\n\n

تستخدم هذه الطريقة التحقق من الحدود في وقت التشغيل. إذا تجاوزت حدود المتجه، سيصاب البرنامج بالذعر (panic). هذا مقبول للأمثلة التعليمية، لكن في كود الإنتاج يجب توخي الحذر.

\n\n

يمكنك استخدام أشكال مختلفة من النطاقات:

\n\n
    \n
  • &vec[..] — المتجه بأكمله
  • \n
  • &vec[2..] — من الفهرس 2 إلى النهاية
  • \n
  • &vec[..3] — من البداية إلى الفهرس 3 (بدون تضمين)
  • \n
  • &vec[1..=3] — من 1 إلى 3 شاملًا
  • \n
\n\n

2. الطريقة .as_slice()

\n\n

تعيد هذه الطريقة شريحة على المتجه بأكمله. إنها أكثر أمانًا من &vec[..] لأنها تعبر بوضوح عن النية:

\n\n
let vec = vec![10, 20, 30];\nlet slice: &[i32] = vec.as_slice();\nprintln!("{:?}", slice); // [10, 20, 30]
\n\n

الطريقة as_slice() مفيدة بشكل خاص عندما تريد التأكيد على أنك تعمل مع شريحة وليس مع متجه. هذا يجعل الكود أكثر قابلية للقراءة والتوثيق الذاتي.

\n\n

3. الحصول على شريحة قابلة للتعديل: as_mut_slice()

\n\n

إذا كنت بحاجة لتعديل العناصر داخل الشريحة (ولكن ليس المتجه نفسه)، استخدم as_mut_slice():

\n\n
let mut vec = vec![1, 2, 3];\nlet slice: &mut [i32] = vec.as_mut_slice();\nslice[0] = 100;\nprintln!("{:?}", vec); // [100, 2, 3]
\n\n

لاحظ: يجب تعريف المتجه كـ mut. كما لا يمكنك الحصول على شرائح غير قابلة للتعديل وقابلة للتعديل في نفس الوقت — فهذا ينتهك قواعد الاقتراض.

\n\n

كيف تحصل على جزء

المدونات

توصيات الكتب