usize مقابل u32 في Rust: ما الفرق وماذا تختار

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

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

ابدأ الدورة

usize مقابل u32: مبارزة أنواع الأعداد الصحيحة في Rust

\n\n

إذا كنت تكتب بلغة Rust لمدة أسبوع على الأقل، فمن المؤكد أنك واجهت هذا الموقف: المترجم يوبخك لأنك تحاول استخدام u32 لفهرسة مصفوفة، بينما هو يتطلب usize. أو العكس — تمرر usize إلى دالة تنتظر u32، وتحصل على موجة حمراء في بيئة التطوير.

\n\n

على Stack Overflow، سؤال «ما الفرق بين usize و u32؟» حصد آلاف المشاهدات. هذا ليس من قبيل الصدفة — فالخلط بين هذين النوعين هو أحد أكثر الفخاخ شيوعًا للمبتدئين في Rust.

\n\n

دعنا ننهي هذا الأمر مرة واحدة وإلى الأبد: ما الفرق بينهما، ومتى تستخدم أيًا منهما، وكيف تتجنب الوقوع في المشاكل. هيا بنا!

\n\n

باختصار: الفرق الرئيسي

\n\n

usize هو عدد صحيح غير موقع، حجمه يعتمد على بنية النظام. على نظام 64 بت، حجمه 8 بايت، وعلى نظام 32 بت، حجمه 4 بايت. u32 هو دائمًا 4 بايت، بغض النظر عن المنصة.

\n\n

لكن الفرق ليس فقط في الحجم. الفرق الرئيسي هو الدلالة:

\n\n
    \n
  • usize — لـ الأحجام، الفهارس، وعدد العناصر في المجموعات
  • \n
  • u32 — لـ البيانات الرقمية التي لا تتجاوز 4 مليارات
  • \n
\n\n

ونعم، المترجم لا يسمح بخلطهما دون تحويل صريح. هذا ليس خطأ، بل ميزة — بهذه الطريقة تحميك Rust من الأخطاء المتعلقة بعرض البت في البنية.

\n\n

لماذا يوجد usize؟

\n\n

تخيل أنك تكتب كودًا يجب أن يعمل على متحكم دقيق قديم 32 بت وعلى خادم حديث 64 بت. طول المصفوفة على نظام 32 بت لا يمكن أن يتجاوز 2^32 - 1 عنصرًا، بينما على نظام 64 بت يمكن أن يصل إلى 2^64 - 1.

\n\n

إذا كنت تستخدم u32 للفهرسة على نظام 64 بت، فلن تتمكن ببساطة من الوصول إلى العناصر التي تتجاوز 4 مليارات — حتى لو كانت الذاكرة كافية. usize يحل هذه المشكلة: فهو دائمًا يسع أكبر حجم ممكن للذاكرة على البنية الحالية.

\n\n
// مثال: usize يتكيف تلقائيًا مع البنية\nfn main() {\n    let large_vec: Vec<u8> = vec![0; 1_000_000_000]; // مليار عنصر\n    \n    // usize يسع هذا الفهرس على أي منصة\n    let index: usize = 999_999_999;\n    println!("العنصر: {}", large_vec[index]);\n    \n    // لكن u32 قد لا يكفي على نظام 32 بت\n    // let bad_index: u32 = 999_999_999; // على نظام 32 بت، سيتم تجميعه، لكن...\n    // large_vec[bad_index as usize]; // ...سيتعين عليك إجراء تحويل\n}
\n\n

مقارنة في جدول

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
الخاصيةusizeu32
الحجم على 64-bit8 بايت4 بايت
الحجم على 32-bit4 بايت4 بايت
النطاق (64-bit)0 .. 2^64-10 .. 2^32-1
الاستخدام الأساسيالفهارس، الأحجام، الأطوالالبيانات الرقمية
التحويل الضمنيلالا
\n\n

متى تستخدم usize؟

\n\n

دائمًا لفهرسة المجموعات. هذه قاعدة لا استثناءات فيها تقريبًا. إذا كتبت vec[i] حيث i من نوع u32، سيقول المترجم: «يا صديقي، استخدم usize من فضلك».

\n\n
// صحيح: استخدام usize للفهارس\nfn get_element(vec: &[i32], index: usize) -> Option<&i32> {\n    vec.get(index)\n}\n\n// غير صحيح: استخدام u32 للفهرسة — سيتعين التحويل\nfn get_ele                

المدونات

توصيات الكتب