שיעורי מודול (2/2)
טיפול בשגיאות וה-? מפעיל
הפילוסופיה של Rust מעודדת אותך לזהות את האפשרות של שגיאות באופן מפורש ולבנות את הקוד שלך כדי לטפל בהן לפני הידור של התוכנית.
שגיאות בחלודה מחולקות לשתי קטגוריות עיקריות: שגיאות בלתי ניתנות לשחזור (שגורמות לסיום מיידי באמצעות המאקרו panic!) ושגיאות ניתנות לשחזור (מנוהלות באמצעות סוג Result<T, E>).
התוצאה<T, E> התאמת סוג ותבנית
רוב השגיאות הניתנות לשחזור מחזירות סוג Result<T, E>, שהוא מנה המוגדרת כ:
enum Result<T, E> {
Ok(T),
Err(E),
}אנו יכולים להשתמש בהתאמת דפוסים כדי לבדוק את התוצאה:
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(...).
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) כדי לספק ייצוג קריא אנושי של השגיאה:
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: קריאת קובץ עם ה-? מַפעִיל
השלם את הפונקציה read_username_from_file כך שהיא תשתמש ב-? אופרטור להפיץ שגיאות שנוצרו על ידי פתיחת הקובץ וקריאת התוכן שלו לתוך מחרוזת שם המשתמש.
הצג רמז
הוסף את התו `?`אחרי`File::open(...)`ואחר `username_file.read_to_string(...)` כדי להפיץ שגיאות.
הפתרון זמין לאחר 3 ניסיונות
תרגיל 2: נתח והכפיל מספר
כתוב פונקציה בשם parse_and_double שמקבלת הפניה למחרוזת &str ומחזירה Result<i32, std::num::ParseIntError>. הפונקציה צריכה לנתח את המחרוזת באמצעות val.parse::<i32>() עם ? להפיץ שגיאות ניתוח, ובהצלחה להחזיר את הערך הכפול עטוף ב- Ok.
הצג רמז
השתמש ב-`val.parse::<i32>()?`כדי לנתח את המחרוזת ולהפיץ את השגיאה, ואז החזר `Ok(num \* 2)`.
הפתרון זמין לאחר 3 ניסיונות
תרגיל 3: הגדרת שגיאה מותאמת אישית
הגדר מבנה ריק בשם CustomError. יישם את תכונת std::fmt::Display עבורו על ידי כתיבת 'Si e verificato un errore personalizzato' כהודעת השגיאה בשיטת fmt.
הצג רמז
הכריז על `struct CustomError;`ויישם את התצוגה על ידי כתיבת `write!(f, "Si e verificato un errore personalizzato")`בתוך שיטת `fmt`.
הפתרון זמין לאחר 3 ניסיונות