Rust Erros Intermediário
Result e o operador ?
Em Rust, o tratamento de erros é explícito: funções que podem falhar retornam Result<T, E>, uma enumeração com as variantes Ok(T) para sucesso e Err(E) para falha. Isso obriga o programador a lidar com os dois casos, evitando exceções não verificadas.
O operador ? simplifica a propagação de erros: se o valor for Ok, ele extrai o conteúdo; se for Err, ele retorna o erro imediatamente da função atual. Isso mantém o código limpo, sem vários match aninhados.
Para usar ? em uma função, o tipo de retorno dela deve ser compatível com o erro propagado. Erros customizados podem ser criados implementando std::error::Error e a conversão From para permitir que ? converta automaticamente entre tipos de erro.
Neste card, você verá como definir seus próprios erros, implementar From e usar ? para escrever código robusto e legível.
Pontos-chave
Result<T, E>tem duas variantes:Ok(T)para sucesso eErr(E)para erro.- O operador
?extrai o valor deOkou retorna oErrimediatamente. ?só pode ser usado em funções cujo retorno éResult(ouOption).- Erros customizados implementam
std::error::ErroreDisplay. - A conversão
Frompermite que?transforme um erro em outro automaticamente.
use std::fmt;
use std::num::ParseIntError;
// Erro customizado
#[derive(Debug)]
enum MeuErro {
Parse(ParseIntError),
Negativo,
}
// Permite converter ParseIntError em MeuErro automaticamente
impl From<ParseIntError> for MeuErro {
fn from(e: ParseIntError) -> Self {
MeuErro::Parse(e)
}
}
impl fmt::Display for MeuErro {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MeuErro::Parse(e) => write!(f, "erro de parse: {}", e),
MeuErro::Negativo => write!(f, "número negativo não permitido"),
}
}
}
// Função que usa ? para propagar erros
fn dobra_numero(s: &str) -> Result<i32, MeuErro> {
let n: i32 = s.parse()?; // converte ParseIntError em MeuErro via From
if n < 0 {
return Err(MeuErro::Negativo);
}
Ok(n * 2)
}
fn main() {
println!("{:?}", dobra_numero("21")); // Ok(42)
println!("{:?}", dobra_numero("-5")); // Err(Negativo)
println!("{:?}", dobra_numero("abc")); // Err(Parse(...))
}