Menu
Coddy logo textTech

אופרטור סימן השאלה '?'

חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-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) // אם הפענוח הצליח, הכפל את המספר ב-2
}

הדבר שקול לכתיבת משפט match מלא, אבל תמציתי הרבה יותר. אם s.parse::<i32>() מחזירה Ok, הסימן ? מחלץ את הערך ומשייך אותו אל number. אם היא מחזירה Err, הסימן ? מחזיר מיד את השגיאה הזו מכל הפונקציה.

שימו לב לתחביר ::<i32>. הוא נקרא turbofish, והוא מורה ל-Rust לאיזה טיפוס לנתח את המחרוזת. הפונקציה מחזירה Result<i32, std::num::ParseIntError>, כאשר i32 הוא טיפוס ההצלחה ו-std::num::ParseIntError הוא טיפוס השגיאה שמוחזר כאשר הניתוח נכשל.

אפשר להשתמש באופרטור ? רק בפונקציות שמחזירות Result (או Option), מכיוון שהוא צריך להיות מסוגל להחזיר שגיאה.

challenge icon

אתגר

קל

תקבלו שתי קלטים. הקלט הראשון הוא מחרוזת שיש לנתח למספר שלם, והקלט השני הוא מחרוזת נוספת שגם אותה יש לנתח למספר שלם. צרו פונקציה בשם add_numbers שמקבלת שתי פרוסות מחרוזת כפרמטרים ומחזירה 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

נסו בעצמכם

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בחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה לוגיקה וזרימת תוכנית

תרגלו בעצמכם: קומפיילר Rust אונליין