Salt la conținutul principal
Modulul 7 · Lecția 2 din 214/14 în curs~15 min
Lecții din modul (2/2)

Gestionarea erorilor și ? Operator

Filosofia lui Rust vă încurajează să recunoașteți posibilitatea erorilor în mod explicit și să vă structurați codul pentru a le gestiona înainte ca programul să fie compilat.

Erorile din Rust sunt împărțite în două categorii principale: erori irecuperabile (care provoacă încetarea imediată prin intermediul macrocomenzii panic!) și erori recuperabile (gestionate folosind tipul Result<T, E>).


Potrivirea tipului și modelului Rezultatul<T, E>

Cele mai multe erori recuperabile returnează un tip Result<T, E>, care este o enumerare definită ca:

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

Putem folosi potrivirea modelului pentru a inspecta rezultatul:

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),
    };
}

Propagarea erorilor cu operatorul ?

Când implementăm o funcție, în loc să gestionăm eroarea direct în ea, deseori dorim să returnăm eroarea apelantului, astfel încât acesta să poată decide ce să facă. Acest proces se numește propagarea erorilor.

Rust oferă operatorul ? ca scurtătură sintactică pentru a propaga erori. Dacă valoarea unui Result este Ok, valoarea interioară a lui Ok este returnată de expresie; dacă este Err, eroarea Err este returnată din întreaga funcție curentă ca și cum am fi folosit un 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)
}

[!IMPORTANT] Operatorul ? poate fi utilizat numai în funcțiile care returnează un tip compatibil cu valoarea căreia i se aplică (de obicei Result, Option sau tipuri care implementează FromResidual).


Erori personalizate

Ne putem defini propriile tipuri de erori personalizate prin implementarea trăsăturii std::fmt::Display (și opțional std::error::Error) pentru a oferi o reprezentare care poate fi citită de om a erorii:

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 {}

Încercați-l singur

Exercițiul 1: Citirea unui fișier cu ? operator

Exercițiu#rust.m7.l2.e1
Încercări: 0Se încarcă…

Completați funcția read_username_from_file astfel încât să folosească ? operator pentru a propaga erorile generate prin deschiderea fișierului și citirea conținutului acestuia în șirul numelui de utilizator.

Se încarcă editorul...
Afișează indiciu

Adăugați caracterul `?` după`File::open(...)`și după`username_file.read_to_string(...)` pentru a propaga erori.

Soluție disponibilă după 3 încercări

Exercițiul 2: Analizați și dublați un număr

Exercițiu#rust.m7.l2.e2
Încercări: 0Se încarcă…

Scrieți o funcție numită parse_and_double care acceptă o referință de șir &str și returnează un Rezultat<i32, std::num::ParseIntError>. Funcția ar trebui să analizeze șirul folosind val.parse::<i32>() cu ? pentru a propaga erorile de analiză, iar la succes returnează valoarea dublată încapsulată în Ok.

Se încarcă editorul...
Afișează indiciu

Utilizați `val.parse::<i32>()?` pentru a analiza șirul și a propaga eroarea, apoi returnați`Ok(num \* 2)`.

Soluție disponibilă după 3 încercări

Exercițiul 3: Definirea unei erori personalizate

Exercițiu#rust.m7.l2.e3
Încercări: 0Se încarcă…

Definiți o structură goală numită CustomError. Implementați caracteristica std::fmt::Display pentru aceasta scriind „Si e verificato un errore personalizzato” ca mesaj de eroare în metoda fmt.

Se încarcă editorul...
Afișează indiciu

Declarați `struct CustomError;`și implementați Display scriind`write!(f, "Si e verificato un error personalizzato")`în cadrul metodei`fmt`.

Soluție disponibilă după 3 încercări