Capítulo 14: Tratamento de Erros (Option e Result) 🤠💎

Neste capítulo, vamos aprender como o Rust lida com erros sem usar exceções (como o try/catch de outras linguagens), usando os tipos Option e Result, com o tema Indiana Jones!


📖 O que são Option e Result?

No Rust, não existe o valor null (nulo) para evitar o famoso erro de “ponteiro nulo”. Em vez disso, o Rust usa duas enums especiais:

  1. Option<T>: Usado quando algo pode ou não ter um valor. Tem as variantes Some(valor) e None (nada).
  2. Result<T, E>: Usado quando uma operação pode dar certo ou dar erro. Tem as variantes Ok(valor) e Err(erro).

📖 Exemplo Guiado: Em busca do Santo Graal (Option)

Vamos criar uma função que busca um tesouro em uma lista. Se encontrar, retorna Some, se não, retorna None.

  1. Crie o arquivo busca_tesouro.rs na pasta src/:
fn buscar_tesouro(id: i32) -> Option<String> {
    if id == 7 {
        Some(String::from("Santo Graal"))
    } else {
        None // Não encontrou nada
    }
}
 
fn main() {
    let tentativa1 = buscar_tesouro(5);
    let tentativa2 = buscar_tesouro(7);
 
    // Usando match para tratar o Option
    match tentativa1 {
        Some(tesouro) => println!("Indiana Jones encontrou o {}!", tesouro),
        None => println!("Tentativa 1: Apenas poeira..."),
    }
 
    match tentativa2 {
        Some(tesouro) => println!("Indiana Jones encontrou o {}!", tesouro),
        None => println!("Tentativa 2: Apenas poeira..."),
    }
}

🕹️ Como Executar e Testar no VS Code

  1. Abra le terminal integrado.
  2. Compile: rustc busca_tesouro.rs
  3. Execute: ./busca_tesouro

Resultado Esperado:

Tentativa 1: Apenas poeira...
Indiana Jones encontrou o Santo Graal!

📊 Ilustração Visual: O Tipo Option

Veja como o Rust nos obriga a tratar a ausência de valor:

graph TD
    A[Função buscar_tesouro] -->|Sucesso| B["Some('Santo Graal')"]
    A -->|Falha| C[None]

🛠️ Prática Obrigatória 1: Desarmando Armadilhas (Result)

Crie uma função chamada desarmar_armadilha(codigo: i32) -> Result<String, String>. Se o código for 1234, retorne Ok com a mensagem “Armadilha desarmada!“. Se for qualquer outro número, retorne Err com a mensagem “CABUM! A armadilha disparou!“. Teste os dois casos na main usando match.


🔑 Gabarito de Código

Prática 1: armadilha_result.rs

fn desarmar_armadilha(codigo: i32) -> Result<String, String> {
    if codigo == 1234 {
        Ok(String::from("Armadilha desarmada!"))
    } else {
        Err(String::from("CABUM! A armadilha disparou!"))
    }
}
 
fn main() {
    let tentativa = desarmar_armadilha(9999);
 
    match tentativa {
        Ok(msg) => println!("Sucesso: {}", msg),
        Err(erro) => println!("Erro: {}", erro),
    }
}

Capitulo Anterior | Proximo Capitulo