Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

عامل علامة الاستفهام '?'

جزء من قسم المنطق وتدفّق التنفيذ في رحلة Rust على Coddy. الدرس 46 من 66.

عند العمل مع الدوال التي تُرجع Result، غالبًا ما تحتاج إلى handle الأخطاء إما بالتعامل معها محليًا أو بتمريرها إلى الدالة المستدعِية. توفّر Rust معاملًا أنيقًا لهذا النمط الشائع: معامل علامة الاستفهام ?.

يوفّر العامل ? طريقة واضحة لتمرير الأخطاء دون كتابة عبارات match مطوّلة. عند وضع ? بعد Result، فإنه يفك تلقائيًا قيمة Ok أو يعيد التنفيذ فورًا من الدالة الحالية مع Err:

fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // إذا فشل التحليل، أعد الخطأ
    Ok(number * 2) // إذا نجح، ضاعف الرقم
}

هذا يعادل كتابة عبارة match كاملة، لكنه أكثر اختصارًا بكثير. إذا أعاد s.parse::<i32>() قيمة Ok، فإن ? يستخرج القيمة ويُسنِدها إلى number. وإذا أعاد قيمة Err، فإن ? يعيد ذلك الخطأ فورًا من كامل function.

لاحظ صيغة ::<i32>. تُسمّى هذه الصيغة turbofish، وهي تخبر Rust بالنوع الذي يجب تحليل السلسلة النصية إليه. تُرجع الدالة Result<i32, std::num::ParseIntError>، حيث إن i32 هو نوع النجاح، وstd::num::ParseIntError هو نوع الخطأ الذي يتم إرجاعه عند فشل parsing.

لا يمكن استخدام المعامل ? إلا في الدوال التي تُرجع Result (أو Option)، لأنه يحتاج إلى أن يتمكن من إرجاع خطأ.

challenge icon

التحدي

سهل

ستتلقى مدخلين. المدخل first هو سلسلة نصية ينبغي تحليلها إلى عدد صحيح، والمدخل second هو سلسلة نصية أخرى ينبغي أيضًا تحليلها إلى عدد صحيح. أنشئ دالة تُسمى add_numbers تتلقى شريحتي نص كـ parameters وتُرجع قيمة من النوع Result<i32, std::num::ParseIntError>. داخل الدالة، استخدم عامل ? لتحليل السلسلتين وإرجاع مجموعهما مغلفًا داخل Ok. استدعِ الدالة باستخدام المدخلين وتعامل مع result باستخدام match.

المتطلبات:

  • اقرأ المدخل first (العدد first كسلسلة نصية) وأزل المسافات البيضاء
  • اقرأ المدخل second (العدد second كسلسلة نصية) وأزل المسافات البيضاء
  • أنشئ دالة add_numbers تتلقى اثنين من &str كـ parameters وتُرجع Result<i32, std::num::ParseIntError>
  • داخل الدالة، حلّل السلسلة first إلى i32 باستخدام عامل ?
  • حلّل السلسلة second إلى i32 باستخدام عامل ?
  • أرجع Ok(sum) حيث إن sum هو جمع العددين اللذين تم تحليلهما
  • استدعِ الدالة باستخدام سلسلتي الإدخال
  • استخدم تعبير match للتعامل مع Result
  • في ذراع Ok(value)، اطبع: Sum: [value]
  • في ذراع Err(_)، اطبع: Parsing error

المدخل:

  • السطر first: سلسلة نصية تمثل عددًا (مثلًا: 15)
  • السطر second: سلسلة نصية تمثل عددًا آخر (مثلًا: 27)

المخرج:

  • إذا كانت كلتا السلسلتين عددين صالحين: Sum: [result]
  • إذا تعذر تحليل أي من السلسلتين: Parsing error

جرّب بنفسك

use std::io;

// TODO: أنشئ دالة add_numbers هنا
// يجب أن تأخذ معاملين من نوع &str وتُرجع Result<i32, std::num::ParseIntError>


fn main() {
    // اقرأ الإدخال الأول
    let mut input1 = String::new();
    io::stdin().read_line(&mut input1).expect("Failed to read line");
    let input1 = input1.trim();
    
    // اقرأ الإدخال الثاني
    let mut input2 = String::new();
    io::stdin().read_line(&mut input2).expect("Failed to read line");
    let input2 = input2.trim();
    
    // TODO: استدعِ add_numbers مع input1 و input2
    // TODO: استخدم match للتعامل مع Result
    // اطبع "Sum: [value]" من أجل Ok(value)
    // Print "Parsing error" for Err(_)
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس المنطق وتدفّق التنفيذ

تدرّب بنفسك: مترجم Rust عبر الإنترنت