דילוג לתוכן המרכזי
מודול 7 · שיעור 2 מתוך 214/14 בקורס~15 min
שיעורי מודול (2/2)

טיפול בשגיאות וה-? מפעיל

הפילוסופיה של Rust מעודדת אותך לזהות את האפשרות של שגיאות באופן מפורש ולבנות את הקוד שלך כדי לטפל בהן לפני הידור של התוכנית.

שגיאות בחלודה מחולקות לשתי קטגוריות עיקריות: שגיאות בלתי ניתנות לשחזור (שגורמות לסיום מיידי באמצעות המאקרו panic!) ושגיאות ניתנות לשחזור (מנוהלות באמצעות סוג Result<T, E>).


התוצאה<T, E> התאמת סוג ותבנית

רוב השגיאות הניתנות לשחזור מחזירות סוג Result<T, E>, שהוא מנה המוגדרת כ:

Rust
enum Result<T, E> {
    Ok(T),
    Err(E),
}

אנו יכולים להשתמש בהתאמת דפוסים כדי לבדוק את התוצאה:

Rust
use std::fs::File;

fn main() {
    let greeting_file_result = File::open("hello.txt");

    let greeting_file = match greeting_file_result {
        Ok(file) => file,
        Err(error) => panic!("Problem opening the file: {:?}", error),
    };
}

הפצת שגיאה עם המפעיל ?

בעת הטמעת פונקציה, במקום לטפל בשגיאה ישירות בתוכה, לעתים קרובות אנו רוצים להחזיר את השגיאה למתקשר כדי שיוכל להחליט מה לעשות. תהליך זה נקרא הפצת שגיאות.

Rust מספק את האופרטור ? כקיצור דרך תחבירי להפצת שגיאות. אם הערך של Result הוא Ok, הערך הפנימי של Ok מוחזר על ידי הביטוי; אם זה Err, השגיאה Err מוחזרת מכל הפונקציה הנוכחית כאילו השתמשנו ב-return Err(...).

Rust
use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut username_file = File::open("username.txt")?;
    let mut username = String::new();
    username_file.read_to_string(&mut username)?;
    Ok(username)
}

[!חשוב] האופרטור ? יכול לשמש רק בפונקציות המחזירות סוג תואם לערך עליו הוא מוחל (בדרך כלל Result, Option, או סוגים המטמיעים FromResidual).


שגיאות מותאמות אישית

אנו יכולים להגדיר סוגי שגיאות מותאמים אישית משלנו על ידי יישום התכונה std::fmt::Display (ובאופציה std::error::Error) כדי לספק ייצוג קריא אנושי של השגיאה:

Rust
use std::fmt;

#[derive(Debug)]
struct MyError {
    details: String,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Error: {}", self.details)
    }
}

impl std::error::Error for MyError {}

נסה זאת בעצמך

תרגיל 1: קריאת קובץ עם ה-? מַפעִיל

פעילות גופנית#rust.m7.l2.e1
ניסיונות: 0טוען...

השלם את הפונקציה read_username_from_file כך שהיא תשתמש ב-? אופרטור להפיץ שגיאות שנוצרו על ידי פתיחת הקובץ וקריאת התוכן שלו לתוך מחרוזת שם המשתמש.

טוען עורך...
הצג רמז

הוסף את התו `?`אחרי`File::open(...)`ואחר `username_file.read_to_string(...)` כדי להפיץ שגיאות.

הפתרון זמין לאחר 3 ניסיונות

תרגיל 2: נתח והכפיל מספר

פעילות גופנית#rust.m7.l2.e2
ניסיונות: 0טוען...

כתוב פונקציה בשם parse_and_double שמקבלת הפניה למחרוזת &str ומחזירה Result<i32, std::num::ParseIntError>. הפונקציה צריכה לנתח את המחרוזת באמצעות val.parse::<i32>() עם ? להפיץ שגיאות ניתוח, ובהצלחה להחזיר את הערך הכפול עטוף ב- Ok.

טוען עורך...
הצג רמז

השתמש ב-`val.parse::<i32>()?`כדי לנתח את המחרוזת ולהפיץ את השגיאה, ואז החזר `Ok(num \* 2)`.

הפתרון זמין לאחר 3 ניסיונות

תרגיל 3: הגדרת שגיאה מותאמת אישית

פעילות גופנית#rust.m7.l2.e3
ניסיונות: 0טוען...

הגדר מבנה ריק בשם CustomError. יישם את תכונת std::fmt::Display עבורו על ידי כתיבת 'Si e verificato un errore personalizzato' כהודעת השגיאה בשיטת fmt.

טוען עורך...
הצג רמז

הכריז על `struct CustomError;`ויישם את התצוגה על ידי כתיבת `write!(f, "Si e verificato un errore personalizzato")`בתוך שיטת `fmt`.

הפתרון זמין לאחר 3 ניסיונות