أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول
البرمجة بالعربي

Rust Ownership للمبتدئ: ليه الكومبايلر بيرفض كودك قبل ما يشتغل

📅 ١٠ مايو ٢٠٢٦⏱ 6 دقائق قراءة
Rust Ownership للمبتدئ: ليه الكومبايلر بيرفض كودك قبل ما يشتغل
مستوى المقال: مبتدئ

لو الكومبايلر بتاع Rust بيرفض كودك بأخطاء غريبة زي "value borrowed here after move"، إنت مش بتقابل bug — إنت بتقابل أهم ميزة في اللغة. الـ Ownership هو السبب اللي بيخلّي Rust أسرع من Go وأأمن من C++ بدون garbage collector. في الـ 8 دقايق الجاية هتفهم المفهوم ده بمثال بسيط من حياتك اليومية، وبعدين بشكل علمي دقيق، وهتعرف ليه كل مهندس باكاند جاد بيتعلمه سنة 2026.

Rust Ownership: المفهوم اللي بيغيّر طريقة تفكيرك في الذاكرة

شاشة محرر كود تعرض كود Rust ملوّن بألوان داكنة لشرح مفهوم Ownership

المشكلة باختصار

أي لغة برمجة محتاجة طريقة تتحكم بيها في الذاكرة. لغات زي C و C++ بتسيب القرار للمبرمج، فبتحصل أخطاء كارثية زي use-after-free و double-free. تقرير رسمي من Microsoft Security Response Center سنة 2019 رصد إن 70% من ثغرات الأمان في كود Microsoft أصلها memory safety. لغات زي Java و Python و Go بتحلّ المشكلة بـ Garbage Collector، بس بتدفع التمن في pause times و memory overhead.

Rust اخترع طريقة تالتة: Ownership. بدل ما تسيب الذاكرة للمبرمج (خطر) أو لـ GC (بطء)، الكومبايلر نفسه بيتأكد إن كل byte في الذاكرة ليه مالك معروف، وبيحرّرها أوتوماتيكي لمّا المالك يخلص شغله.

المثال البسيط: الكتاب اللي إنت اشتريته

تخيّل إنك اشتريت كتاب من المكتبة. الكتاب ده ملكك إنت. لو صديقك سألك "ممكن أقراه؟" قدامك خياران:

  1. تديهوله وتقوله "خد، بقى ملكك" — في اللحظة دي إنت مش قادر تقراه تاني، لأنك ادّيته. النسخة دلوقتي عند صديقك بس.
  2. تسلّفه الكتاب لمدة محددة — صديقك بيقرا، وإنت ممكن تستنى ترجع تاخده. لكن لو حاولتوا تكتبوا فيه ملاحظات في نفس اللحظة، الكلام هيتلخبط.

القاعدة الواقعية بسيطة: الكتاب لازم يبقى عند شخص واحد بصلاحية الكتابة في كل لحظة. لو نسخت الكتاب وادّيته لـ 10 أصحاب، وكل واحد فيهم عدّل في النص، مفيش طريقة تعرف أنهي نسخة هي الصح.

Rust بيطبّق نفس القاعدة دي على الذاكرة بالظبط: كل قيمة في البرنامج ليها مالك واحد فقط (owner) في كل وقت. لما المالك يخرج من scope، الذاكرة بتتحرّر تلقائياً. مفيش garbage collector، مفيش free() يدوي، مفيش حتى ثانية واحدة في تشغيل البرنامج بتتصرف على إدارة الذاكرة.

التعريف العلمي الدقيق

Ownership في Rust هو نموذج لإدارة الذاكرة مبني على ثلاث قواعد ثابتة، مكتوبة حرفياً في توثيق Rust الرسمي (The Rust Programming Language Book — Chapter 4):

  1. كل قيمة في Rust ليها متغير واحد بيُسمّى الـ owner.
  2. القيمة ليها owner واحد فقط في كل وقت (no aliasing of mutable state).
  3. لما الـ owner يخرج من الـ scope، القيمة بتتحرّر (dropped) تلقائياً.

القواعد دي بتُفحص compile-time بواسطة جزء من الكومبايلر اسمه borrow checker. يعني الأخطاء بتطلع قبل ما البرنامج يشتغل أصلاً. ده بيختلف جذرياً عن Garbage Collection اللي بيشتغل runtime ويوقف البرنامج لحظات (stop-the-world pauses) عشان يلمّ الذاكرة المهجورة.

الكود اللي بيكسر بسبب Ownership

Rust
fn main() {
    let s1 = String::from("مرحبا");
    let s2 = s1;                      // الـ ownership اتنقل من s1 لـ s2

    println!("{}", s1);               // خطأ! s1 مش مالك القيمة دلوقتي
}

الكود ده بيرفضه الكومبايلر بالرسالة: error[E0382]: borrow of moved value: \`s1\`. اللي حصل إن السطر let s2 = s1 ما عملش نسخة من String — هو نقل الـ ownership من s1 لـ s2 (operation اسمها move). من اللحظة دي، s1 بقى invalid ومينفعش تقراه.

ليه؟ لأن String في الذاكرة عبارة عن pointer بيشاور على بيانات في الـ heap. لو سمح Rust للاتنين (s1 و s2) إنهم يبقوا ملاك لنفس الـ pointer، أول واحد فيهم يخرج من scope هيحرّر الذاكرة، والتاني هيشاور على memory محرّرة (use-after-free). الـ borrow checker بيمنع السيناريو ده compile-time من غير أي runtime cost.

صناديق تخزين مرتّبة فوق بعضها كتمثيل بصري لـ blocks الذاكرة في نموذج Ownership

Borrowing: لما تحتاج تشارك بدون نقل ملكية

لو ما عرفناش حل غير الـ move، البرامج كلها هتبقى وجع دماغ. هنا بييجي الـ Borrowing — إنت بتسلّف القيمة بدل ما تنقل ملكيتها. ارجع لمثال الكتاب: لما تسلّف صديقك الكتاب لساعة وترجعه، الملكية فضلت معاك.

Rust
fn main() {
    let s1 = String::from("مرحبا");
    let length = calculate_length(&s1);   // & = استلاف reference

    println!("الطول: {} | النص: {}", length, s1);  // s1 لسه ملك main
}

fn calculate_length(s: &String) -> usize {
    s.len()
}                                           // s بتخرج من scope بس مالكش القيمة

الـ & معناها "اقترض reference بدل نقل ownership". القاعدة العلمية للـ Borrowing بسيطة لكنها صارمة:

  • عدد لا نهائي من immutable references (&T) في نفس الوقت — قراءة فقط.
  • أو reference واحد mutable فقط (&mut T) — تعديل، بدون أي references تانية معاه في نفس اللحظة.

القاعدة دي اسمها "aliasing XOR mutability" وهي اللي بتمنع data races compile-time. حسب ورقة RustBelt: Securing the Foundations of the Rust Programming Language (POPL 2018) من Ralf Jung وزملاؤه في Max Planck Institute، القاعدة دي مُثبتة رياضياً إنها بتمنع كل data races في الكود الـ safe بدون أي runtime overhead.

الـ trade-offs الحقيقية

Ownership مش هدية مجانية. إنت بتدفع تمنه:

  • منحنى تعلم حاد: أول 3-4 أسابيع هتقاتل الكومبايلر. Stack Overflow Developer Survey 2024 أظهر إن Rust الأصعب في التعلم لكنه الأكثر "محبوبية" 9 سنوات على التوالي (83% من المطورين اللي جرّبوه عايزين يكملوا شغل بيه).
  • كود أطول: برنامج Rust بيبقى أطول 20-30% من نفس البرنامج بـ Go غالباً، عشان كل reference و lifetime لازم يبقى صريح.
  • refactoring أبطأ في البداية: تغيير struct واحد ممكن يضرب 12 ملف ولازم تصلّحهم كلهم قبل ما الكود يبني تاني.
  • المكسب الفعلي: صفر null pointer exceptions، صفر data races، صفر buffer overflows في الـ safe code. بنشمارك من Discord Engineering أظهر تقليل P99 latency من 300ms (بـ Go) لـ 20ms (بـ Rust) بعد إعادة كتابة Read States Service، مع اختفاء كامل للـ GC pauses.

متى لا تستخدم Rust أصلاً

Rust مش الحل في كل حالة، وده مهم جداً تعرفه قبل ما تتحمّس:

  • سكربتات سريعة وأدوات داخلية: Python أو Go أسرع 5x في وقت التطوير. لو هتكتب سكربت بيشتغل مرة في الشهر، ما تستحقش 4 ساعات قتال مع الـ borrow checker.
  • prototypes تجربة فكرة: Ownership هيبطّأك. اعمل prototype بـ TypeScript أو Python الأول، وبعد ما الفكرة تثبت قيمتها، أعد كتابة الـ hot path بـ Rust.
  • مشاريع فريق مبتدئ: لو الفريق ما عندوش 3-4 أسابيع للتعلم، التكلفة هتبقى أعلى من المكسب. اختيار Go غالباً أحكم.
  • تطبيقات GC-friendly: Web servers بـ traffic معتدل ومش حساسة بشدة للـ latency، Go أنسب وأبسط ومفيش فيه deadline ضيّق على الذاكرة.

الخطوة التالية

افتح Rust Playground دلوقتي على play.rust-lang.org، انسخ الكود الأول (اللي بيكسر بسبب الـ move)، شغّله وشوف رسالة الكومبايلر بنفسك. بعد كده عدّله باستخدام &s1 بدل s1 وشوف الفرق. لو حصلت confused في موقف معين، اقرا رسالة الخطأ بهدوء — أغلب رسائل Rust بتقولك بالظبط الإصلاح المطلوب، وأحياناً بتقترح الكود البديل حرفياً.

المصادر

  • The Rust Programming Language — Chapter 4: Understanding Ownership (doc.rust-lang.org/book/ch04-00-understanding-ownership.html)
  • Jung et al., RustBelt: Securing the Foundations of the Rust Programming Language, POPL 2018 (plv.mpi-sws.org/rustbelt/popl18)
  • Microsoft Security Response Center — A Proactive Approach to More Secure Code, 2019 (msrc.microsoft.com/blog)
  • Discord Engineering — Why Discord is Switching from Go to Rust, 2020 (discord.com/blog/why-discord-is-switching-from-go-to-rust)
  • Stack Overflow Developer Survey 2024 — Most Admired Languages (survey.stackoverflow.co/2024)
]]>

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة