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

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

جزء من قسم Logic & Flow في رحلة Rust على Coddy — الدرس 46 من 66.

عند العمل مع الدوال التي تُرجع Result، غالباً ما تحتاج إلى معالجة الأخطاء إما عن طريق التعامل معها محلياً أو تمريرها إلى الدالة المستدعية. توفر لغة 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، فإن ? يعيد ذلك الخطأ فوراً من الدالة بأكملها.

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

challenge icon

التحدي

سهل

سوف تتلقى مدخلين. المدخل الأول هو سلسلة نصية يجب تحويلها إلى عدد صحيح، والمدخل الثاني هو سلسلة نصية أخرى يجب تحويلها أيضاً إلى عدد صحيح. قم بإنشاء دالة تسمى add_numbers تأخذ شريحتين نصيتين (string slices) كمعاملات وتعيد Result<i32, std::num::ParseIntError>. داخل الدالة، استخدم عامل التشغيل ? لتحويل كلا السلسلتين وإرجاع مجموعهما ملفوفاً في Ok. قم باستدعاء الدالة مع المدخلين ومعالجة النتيجة باستخدام match.

المتطلبات:

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

المدخلات:

  • السطر الأول: سلسلة نصية تمثل رقماً (مثلاً، 15)
  • السطر الثاني: سلسلة نصية تمثل رقماً آخر (مثلاً، 27)

المخرجات:

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

ورقة مرجعية

يوفر عامل علامة الاستفهام ? طريقة موجزة لنشر الأخطاء في الدوال التي تعيد Result.

عند وضعه بعد Result، يقوم عامل ? بـ:

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

يمكن استخدام عامل ? فقط في الدوال التي تعيد نوع Result أو Option.

جرّب بنفسك

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)
    // اطبع "Parsing error" في حالة Err(_)
}
quiz iconاختبر نفسك

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

جميع دروس Logic & Flow