Tipos de Erros DinĂąmicos

Às vezes, queremos permitir que qualquer tipo de erro seja retornado sem escrever nosso próprio enum cobrindo todas as possibilidades diferentes. O trait std::error::Error torna fácil criar um objeto trait que pode conter qualquer erro.

use std::error::Error;
use std::fs;
use std::io::Read;

fn read_count(path: &str) -> Result<i32, Box<dyn Error>> {
    let mut count_str = String::new();
    fs::File::open(path)?.read_to_string(&mut count_str)?;
    let count: i32 = count_str.parse()?;
    Ok(count)
}

fn main() {
    fs::write("count.dat", "1i3").unwrap();
    match read_count("count.dat") {
        Ok(count) => println!("Contagem: {count}"),
        Err(err) => println!("Erro: {err}"),
    }
}
This slide should take about 5 minutes.

A função read_count pode retornar std::io::Error (de operaçÔes de arquivo) ou std::num::ParseIntError (de String::parse).

Encaixotar (boxing) erros economiza cĂłdigo, mas sacrifica a capacidade de lidar elegantemente com diferentes casos de erro de forma individualizada no programa. Como tal, geralmente nĂŁo Ă© uma boa ideia usar Box<dyn Error> na API pĂșblica de uma biblioteca, mas pode ser uma boa opção em um programa onde vocĂȘ sĂł quer exibir a mensagem de erro em algum lugar.

Certifique-se de implementar o trait std::error::Error ao definir um tipo de erro personalizado para que ele possa ser encaixotado. Mas se vocĂȘ precisa suportar o atributo no_std, tenha em mente que o trait std.error::Error Ă© atualmente compatĂ­vel com no_std apenas em nightly.