مستوى المقال: مبتدئ
لو فتحت ملف Rust وكتبت كود بسيط ولقيت الـ compiler بيرفضه بـ 4 أخطاء وأنت لسه ما شغّلتش حاجة، Rust مش بتتعنّت معاك — هي بتقفل عليك bug ممكن يكلّفك أسبوع debugging في C++ أو ساعتين segfault في الإنتاج. لو فهمت قواعد الـ Ownership الثلاثة اللي في المقال ده، 80% من الأخطاء اللي بتشوفها هتبقى منطقية فجأة.
ليه Ownership هو السبب اللي بيخلّي Rust مختلفة عن أي لغة تانية
في Python و Java و JavaScript فيه Garbage Collector بيمسح الذاكرة لوحده، بس بتكلفة أداء و pauses غير متوقعة. في C و C++ انت بتحرّر الذاكرة يدوي بـ free() أو delete، فلو نسيت بتعمل memory leak، ولو حرّرت مرتين بيحصل crash مفاجئ. Rust بتقفل المشكلة دي وقت الـ compile بدون GC وبدون idiomatic إدارة يدوية.
المثال البسيط قبل التعريف العلمي
تخيّل إن عندك مفتاح شقة واحد. لو ادّيت المفتاح لأخوك، انت ما عدتش معاك مفتاح. لو هو ادّاه لصاحبه، انت كمان مش هتقدر تدخل. في أي لحظة المفتاح ده عند شخص واحد بس — مش اتنين في نفس الوقت. ولما اللي معاه المفتاح يخرج من الموضوع كله، الشقة تتقفل لوحدها.
كده بالظبط Rust بتشتغل. كل قيمة في الذاكرة عندها "مالك" واحد فقط (متغيّر واحد). لما المالك ده يخرج من الـ scope بتاعه (الـ {} اللي حواليه)، Rust بتحرّر الذاكرة تلقائياً. بدون GC، بدون malloc/free يدوي.
التعريف الدقيق: قواعد الـ Ownership الثلاثة
من الفصل الرابع في The Rust Programming Language Book (الكتاب الرسمي على doc.rust-lang.org/book):
- كل قيمة في Rust عندها متغيّر اسمه مالكها (owner).
- القيمة دي ما يقدرش يكون عندها أكتر من مالك واحد في نفس الوقت.
- لما المالك يخرج من الـ scope، القيمة بتتمسح من الذاكرة تلقائياً (Rust بتنادي function اسمها
drop).
القواعد دي بتتطبّق وقت الـ compile، يعني الـ binary النهائي مفيهوش أي overhead في الـ runtime. ده الفرق بين Rust و Java مثلاً.
المثال اللي بيخلّيك تفهم Move في 10 سطور
fn main() {
let s1 = String::from("مرحبا");
let s2 = s1; // الملكية انتقلت من s1 لـ s2
println!("{}", s1); // خطأ compile!
// error[E0382]: borrow of moved value: `s1`
}في JavaScript أو Python الكود ده هيمشي عادي ويطبع "مرحبا". في Rust، السطر اللي بيطبع s1 ما بيشتغلش — لأن الملكية اتنقلت لـ s2. العملية دي اسمها "move"، والـ compiler بيمنعك من استخدام متغير بعد ما تنقل ملكيته.
الحل لو محتاج تستخدم الاتنين: استخدم اللي بيعمل نسخة كاملة في الذاكرة: