Skip to main content

Result | Rust

  • Result | Rust

Result no Rust

Result é um tipo fundamental da biblioteca padrão do Rust usado para representar operações que podem ter sucesso ou falhar, de forma explícita e segura.

Ele substitui o uso de exceções presentes em outras linguagens e força o tratamento de erros em tempo de compilação.


Definição

A definição simplificada de Result é:

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

Onde:

  • T representa o tipo retornado em caso de sucesso
  • E representa o tipo do erro em caso de falha

Motivação

Rust não possui exceções (try/catch). Em vez disso, erros fazem parte do tipo de retorno da função.

Isso garante que:

  • erros não sejam ignorados acidentalmente
  • o fluxo de erro seja explícito
  • o compilador ajude a manter o código seguro

Exemplo básico

fn parse_number(value: &str) -> Result<i32, String> {
value.parse::<i32>().map_err(|_| "valor inválido".into())
}

Uso com match:

match parse_number("10") {
Ok(n) => println!("Número: {}", n),
Err(e) => println!("Erro: {}", e),
}

Operador ?

O operador ? é usado para propagar erros automaticamente.

fn process() -> Result<(), String> {
let number = parse_number("10")?;
println!("{}", number);
Ok(())
}

Se parse_number retornar Err, a função process retorna imediatamente esse erro.


Comparação com Option

TipoUso
Option<T>Quando um valor pode ou não existir
Result<T, E>Quando uma operação pode falhar com erro

Exemplos comuns:

  • Buscar algo em uma lista → Option
  • Validar entrada do usuário → Result

Erros tipados

Em código de produção, o tipo de erro normalmente é um enum, não uma String.

#[derive(Debug)]
enum ValidationError {
EmptyName,
InvalidPrice,
}
fn validate_name(name: &str) -> Result<(), ValidationError> {
if name.is_empty() {
Err(ValidationError::EmptyName)
} else {
Ok(())
}
}

Isso permite:

  • melhor controle de erros
  • pattern matching mais preciso
  • código mais robusto

Result em validações

Um padrão comum em Rust é usar Result para validações:

struct Product {
name: String,
price: f64,
}

impl Product {
fn validate(&self) -> Result<(), String> {
if self.name.is_empty() {
return Err("nome inválido".into());
}

if self.price <= 0.0 {
return Err("preço inválido".into());
}

Ok(())
}
}

Result e APIs Web

Em aplicações web, Result é usado para:

  • validar payloads
  • mapear erros para respostas HTTP
  • interromper fluxo de execução de forma segura

Exemplo conceitual:

fn handler(product: Product) -> Result<Response, ApiError> {
product.validate()?;
Ok(Response::success())
}

Garantias oferecidas

  • Todo erro possível aparece na assinatura da função
  • Não há exceções implícitas
  • O fluxo de erro é previsível
  • O compilador força tratamento adequado