تخطَّ إلى المحتوى

Option<T> / Result<T, E>

التعامل مع الغياب والأخطاء Option<T> / Result<T, E>

Option<T> تمثّل قيمة قد تكون موجودة أو غائبة، وResult<T, E> تمثّل عملية قد تنجح أو تفشل — بدون null وبدون استثناءات.

Rust لا تملك null؛ بدلًا منه Option<T> وهو enum بمتغيّرين: Some(T) للقيمة الموجودة، وNone للغياب. وبالمثل، لا تملك Rust استثناءات تقليدية للأخطاء المتوقّعة؛ بدلًا منها Result<T, E> بمتغيّرين: Ok(T) للنجاح، وErr(E) للفشل.

المترجم يجبرك على معالجة الحالتين صراحة (عبر match أو توابع مثل unwrap_or)، فلا يمكن أن يمرّ برنامجك بغياب قيمة أو خطأ دون أن تلاحظه، خلافًا للغات تسمح بتجاهل استثناء أو null دون قصد.

الصياغة

enum Option<T> { Some(T), None }
enum Result<T, E> { Ok(T), Err(E) }

📄 مثال

fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("القسمة على صفر"))
    } else {
        Ok(a / b)
    }
}

match divide(10.0, 2.0) {
    Ok(v) => println!("الناتج {v}"),
    Err(e) => println!("خطأ: {e}"),
}

let x: Option<i32> = Some(5);
println!("{}", x.unwrap_or(0));

أهم النقاط

العنصرالوظيفة
Some(v) / Noneمتغيّرا Option — قيمة موجودة أو غياب تام
Ok(v) / Err(e)متغيّرا Result — نجاح بقيمة أو فشل بخطأ
.unwrap_or(default)يستخرج القيمة أو يعيد قيمة افتراضية بدل panic
?ينشر Err أو None تلقائيًا للخارج من دالة، أو يستخرج القيمة عند النجاح

💡 نصائح عملية

  • فضّل ? على match المتكرّر داخل دوال تُعيد Result بنفسها — أنظف وأقصر بكثير
  • استخدم unwrap()/expect() فقط في نماذج أولية أو حالات تعرف يقينًا أنها لن تفشل — لا في كود إنتاجي

⚠️ أخطاء شائعة

  • استخدام unwrap() على قيمة قد تكون None أو Err في كود إنتاجي — يسبّب panic ويوقف البرنامج
  • محاولة استخدام ? داخل دالة main العادية أو دالة لا تُعيد Result/Option أصلًا — خطأ ترجمة

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار RUST الكامل بالعربي.