مستوى المقال: مبتدئ
لو فتحت ملف 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 بيمنعك من استخدام متغير بعد ما تنقل ملكيته.
الحل لو محتاج تستخدم الاتنين: استخدم clone اللي بيعمل نسخة كاملة في الذاكرة:
fn main() {
let s1 = String::from("مرحبا");
let s2 = s1.clone(); // نسخة منفصلة في الذاكرة
println!("{} و {}", s1, s2); // شغّال
}Borrowing: الاستعارة بدل النقل أو النسخ
المشكلة إن clone بيكلّف ذاكرة وأداء. لو الـ String كان 4MB، هتدفع تمن نسخة كاملة كل مرة. الحل اسمه "borrowing" — تستعير القيمة بدون ما تاخد ملكيتها، باستخدام &.
fn print_length(s: &String) -> usize {
s.len() // بنقرأ بس، مش بناخد ملكية
}
fn main() {
let s = String::from("مرحبا");
let len = print_length(&s); // استعارة (borrow)
println!("الطول: {}، النص: {}", len, s); // s لسه مملوكة
}القاعدة المهمة في الـ borrowing: في أي لحظة تقدر يكون عندك إما reference واحدة قابلة للتعديل (&mut)، أو عدد لانهائي من references للقراءة فقط (&) — مش الاتنين في نفس الوقت. ده بالظبط اللي بيمنع data races في الكود المتوازي على مستوى الـ compiler، قبل ما الكود يشتغل أصلاً.
الأرقام: ليه الموضوع ده مش رفاهية أكاديمية
تقرير Microsoft Security Response Center سنة 2019 بيقول إن 70% من الثغرات الأمنية الحرجة في Windows على مدار 12 سنة كانت بسبب memory safety bugs (use-after-free، buffer overflow، double-free). كل النوع ده من الـ bugs مستحيل يحصل في Rust آمنة بدون unsafe.
Mozilla قاست في 2017 إن إعادة كتابة CSS engine بـ Rust (مشروع Stylo داخل Firefox Quantum) خلّت رسم الصفحات أسرع 2x، مع صفر memory bugs في الإنتاج لمدة 24 شهر. Dropbox نقلت magic-pocket storage engine من Go لـ Rust في 2016 وقاست توفير 250GB ذاكرة لكل سيرفر.
Trade-offs حقيقية محدش بيقولهالك
- منحنى تعلّم حاد: هتقعد من شهرين لـ 3 شهور قبل ما تكتب كود من غير ما تحارب الـ borrow checker. نفس البرنامج بتكتبه في Python في أسبوع.
- أوقات compile أطول: مشروع متوسط في Rust بياخد 40 ثانية compile incremental، نفسه في Go بياخد 4 ثواني. على CI ده فرق ساعة يومياً.
- Async معقد: الـ
async/awaitفي Rust محتاج فهم عميق للـ lifetimes وPin، حاجة مش هتحتاجها في Node.js. - ecosystem أصغر: مكتبات الـ web framework (Axum، Actix) ممتازة لكن مجتمعها أصغر من Express أو Django، ولو محتاج SDK لأي service غريب يمكن متلاقيهوش.
متى لا تستخدم Rust
لو بتعمل MVP لازم يخرج خلال أسبوعين، أو فريقك ما عندوش وقت لـ 3 شهور تعلّم، أو الـ workload بتاعك CRUD بسيط مالوش حساسية في الأداء — استخدم Go أو Python أو TypeScript. Rust بتتألق في: أنظمة embedded، blockchain، databases (TiKV، SurrealDB)، game engines، browser engines، أنظمة تشغيل، أي حاجة محتاجة أداء C مع أمان الذاكرة.
الخطوة التالية
افتح rustup.rs ونصّب Rust في 30 ثانية، بعدين انسخ كود Move اللي فوق وحاول تشغّله. لما الـ compiler يرفضه، شغّل الأمر rustc --explain E0382 هيشرحلك الخطأ بالتفصيل. متستسلمش في أول 10 أخطاء — رسائل compiler Rust بتعلّمك أكتر من أي tutorial فيديو.
المصادر
- The Rust Programming Language Book، الفصل الرابع:
doc.rust-lang.org/book/ch04-00-understanding-ownership.html - Microsoft Security Response Center، "Trends, Challenges, and Shifts in Software Vulnerability Mitigation" (BlueHat IL 2019)
- Mozilla Hacks Blog، "Inside a Super Fast CSS Engine: Quantum CSS" (Lin Clark، 2017)
- Dropbox Tech Blog، "Rewriting the heart of our sync engine" (2020)
- Rust Reference، فصل Ownership and Lifetimes:
doc.rust-lang.org/reference/