Skip to main content

? | interrogação | Rust

  • ? | interrogação | Rust

Operador ? no Rust

O operador ? é usado para propagar erros automaticamente em funções que retornam Result ou Option. Ele reduz código boilerplate e torna o fluxo de erro explícito e legível.


Contexto de uso

O ? pode ser usado quando a expressão à esquerda retorna:

  • Result<T, E>
  • Option<T>

E a função atual retorna o mesmo tipo (ou um tipo compatível).


Funcionamento com Result

Considere a expressão:

catalog_product.validate()?;

Se validate() retornar:

  • Ok(valor) → o valor é desempacotado e a execução continua
  • Err(erro) → a função atual retorna imediatamente Err(erro)

Expansão equivalente

O código com ?:

let value = some_function()?;

É equivalente a:

let value = match some_function() {
Ok(v) => v,
Err(e) => return Err(e),
};

O operador apenas encurta esse padrão comum.


Requisito de compilação

O uso do ? exige que a função onde ele aparece retorne um tipo compatível.

Exemplo inválido:

fn process() {
some_function()?;
}

Exemplo válido:

fn process() -> Result<(), ErrorType> {
some_function()?;
Ok(())
}

? com valor de sucesso

Quando o Ok contém um valor, o ? retorna esse valor para a variável.

fn parse_number() -> Result<i32, String> {
let number = "10".parse::<i32>()?;
Ok(number)
}

Se ocorrer erro no parse, ele é retornado automaticamente.


Funcionamento com Option

O operador ? também funciona com Option.

fn first_item(list: Vec<i32>) -> Option<i32> {
let item = list.first()?;
Some(*item)
}

Se first() retornar None, a função retorna None imediatamente.


O que o operador ? não faz

  • Não imprime erros
  • Não realiza logging
  • Não converte erros em mensagens
  • Não trata erros

Ele apenas propaga o erro para o chamador.


Leitura mental recomendada

Sempre interprete o ? como:

Se der erro, retorne agora. Se der sucesso, continue a execução.