Tratamento de erros em Rust: try/catch e além

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

Introdução: filosofia de tratamento de erros em Rust



Ao contrário de muitas linguagens com exceções (Java, Python, C++), Rust não usa a construção clássica try/catch. Em vez disso, a linguagem oferece uma abordagem mais explícita e type-safe. Erros em Rust não são fluxos de controle ocultos, mas valores de retorno. Isso torna o código previsível e protege contra falhas "silenciosas".



Rust tem dois tipos principais para representar situações de erro:

  • Result<T, E> — para erros recuperáveis (erros de I/O, parsing, lógica de negócios).
  • Option<T> — para ausência de valor (análogo a null, mas seguro).


Neste artigo, vamos explorar como trabalhar com esses tipos, como substituí-los no mundo try/catch e como escrever código robusto em Rust.



1. Result<T, E>: a principal ferramenta de tratamento de erros



O tipo Result é um enum com duas variantes: Ok(T) (sucesso) e Err(E) (erro). Ele é usado na maioria das funções que podem falhar.



1.1. Criando e retornando Result



use std::fs::File;use std::io::Read;

fn read_file(path: &str) -> Result<String, std::io::Error> { let mut file = File::open(path)?; // operador ? — análogo ao try! let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents)}


Aqui, o operador ? é um elemento chave. Ele funciona como try em outras linguagens: se o resultado for Err, a função retorna imediatamente esse erro. Se for Ok, extrai o valor.



1.2. Tratamento com match



A forma mais explícita é usar match:



let result = read_file("config.txt");

match result { Ok(content) => println!("Arquivo lido: {}", content), Err(e) => eprintln!("Erro: {}", e),}


Isso é análogo ao try/catch, porém mais flexível e controlado.



1.3. Métodos auxiliares



  • .unwrap() — causa pânico em caso de erro (apenas para protótipos).
  • .expect(msg) — causa pânico com mensagem personalizada.
  • .unwrap_or(default) — retorna um valor padrão.
  • .is_ok() / .is_err() — verificação de estado.


2. Option<T>: trabalho seguro com ausência de valor



Option é outro enum com as variantes Some(T) e None. Ele substitui null e nullptr, eliminando erros de desreferenciação de ponteiro nulo.



2.1. Exemplo de uso



fn find_user(id: u32) -> Option<String> {    if id == 1 {        Some("Alice".to_string())    } else {        None    }}

let user = find_user(2);println!("Usuário: {}", user.unwrap_or("Convidado".to_string()));


2.2. Combinação com Result



Frequentemente, Option é convertido para Result para tratamento uniforme:



fn get_user_name(id: u32) -> Result<String, String> {    find_user(id).ok_or("Usuário não encontrado".to_string())}


O método .ok_or() transforma Some em Ok e None em Err.



3. Operador ?: substituição elegante para try/catch



O operador ? é um açúcar sintático que desempacota automaticamente Result ou Option. Ele só está disponível em funções que retornam o tipo correspondente.



3.1. Exemplo com encadeamento de chamadas



use std::num::ParseIntError;

fn parse_and_add(a: &str, b: &str) -> Result<i32, ParseIntError> { let x: i32 = a.parse()?; let y: i32 = b.parse()?; Ok(x ```

Blogs

Book Recommendations