String مقابل str في Rust: لماذا يختلط الأمر على المبتدئين وكيف تفهمه نهائياً
\n\nإذا كنت قد بدأت للتو في تعلم Rust، فمن المحتمل أنك واجهت بالفعل هذا الموقف: المترجم يشتكي، وتحاول تمرير String إلى مكان يُتوقع فيه &str، أو العكس. هل يبدو ذلك مألوفاً؟ هذا أحد أكثر الأسئلة شيوعاً على Stack Overflow (آلاف المشاهدات!)، وليس من دون سبب - فالموضوع أساسي حقاً لفهم كيفية عمل الذاكرة في Rust.
في هذه المقالة، سنفهم الفروق بين String و &str، ومتى نستخدم كل نوع، وكيف نتجنب الأخطاء النموذجية. هيا بنا!
إجابة مختصرة لمن هم في عجلة من أمرهم
\n\nإذا كنت بحاجة إلى ذلك الآن - تذكر الأساسيات:
\n\n- \n
String- هو نوع بيانات مالك، قابل للتغيير، وديناميكي، يُخزن في الكومة (heap). \n&str- هو شريحة سلسلة غير قابلة للتغيير (slice)، تشير إلى بيانات مملوكة لشخص آخر. غالباً ما تظهر كـ&str. \n
الآن دعنا نتعمق أكثر.
\n\nما هو String في Rust؟
\n\nString هو نوع يملك بياناته. عندما تنشئ String، يتم تخصيص الذاكرة لها في الكومة، ويمكن أن تنمو السلسلة أو تتقلص أو تتغير.
let mut s = String::from("مرحباً");\ns.push_str("، أيها العالم!");\nprintln!("{}", s); // سيُطبع: مرحباً، أيها العالم!\n\nهنا، s هو مالك السلسلة. عندما يخرج s عن النطاق، يتم تحرير الذاكرة تلقائياً (بفضل RAII - Resource Acquisition Is Initialization).
الخصائص الرئيسية لـ String:
\n- \n
- يملك البيانات (owning type) \n
- قابل للتغيير (mutable) \n
- يُخزن في الكومة \n
- يمكن إنشاؤه من حرف سلسلة نصية:
String::from("نص")\n - يدعم الربط والإدراج وحذف الأحرف \n
ما هو &str في Rust؟
\n\n&str (يُنطق "شريحة سلسلة" أو "سلايس سترينغ") هو مرجع إلى سلسلة من أحرف UTF-8 مملوكة لشخص آخر. في حد ذاته، &str هو مجرد مؤشر للبيانات وطولها.
let greeting: &str = "مرحباً";\nprintln!("{}", greeting);\n\nفي هذا المثال، greeting هو مرجع إلى حرف سلسلة نصية مخزنة مباشرة في الملف الثنائي للبرنامج (في جزء الذاكرة للقراءة فقط). greeting لا يملك هذه البيانات - إنه فقط ينظر إليها.
الخصائص الرئيسية لـ &str:
\n- \n
- لا يملك البيانات (borrowed type) \n
- غير قابل للتغيير (immutable) \n
- يُخزن إما في الملف الثنائي (حروف السلاسل النصية) أو في الكومة (كشريحة من
String) \n - خفيف الوزن - يتكون من حقلين: مؤشر + طول (16 بايت على نظام 64 بت) \n
- مثالي للتمرير إلى الدوال عندما لا تحتاج إلى تعديل السلسلة
الفروق الرئيسية بين String و &str (جدول)
\n\nدعنا نلخص كل شيء في جدول توضيحي:
\n\n| الخاصية | \nString | \n&str | \n
|---|---|---|
| الملكية | \nيملك البيانات | \nيقترض البيانات | \n
| قابلية التغيير | \nنعم (mut) | \nلا | \n
| مكان التخزين | \nالكومة (heap) | \nالكومة، المكدس، أو الملف الثنائي | \n
| الحجم في المكدس | \n24 بايت (ptr + len + cap) | \n16 بايت (ptr + len) | \n
| الإنشاء | \nString::from("...") | \n"..." أو &s[..] | \n
| الاستخدام الرئيسي | \nعند الحاجة إلى التعديل أو ال
المدوناتتوصيات الكتباقرأ أيضًا |