O Operador ?
O ? retorna antecipadamente Err (ou None em contextos Option) e desempacota valores Ok, com conversão automática via From.
Receita
fn load_config(path: &str) -> Result<String, std::io::Error> {
let body = std::fs::read_to_string(path)?;
Ok(body)
}Quando usar: Funções falíveis que retornam Result - preferível a match aninhado.
Exemplo de Funcionamento
#[derive(Debug)]
enum AppError {
Io(std::io::Error),
Parse(std::num::ParseIntError),
}
impl From<std::io::Error> for AppError {
fn from(e: std::io::Error) -> Self { AppError::Io(e) }
}
impl From<std::num::ParseIntError> for AppError {
fn from(e: std::num::ParseIntError) -> Self { AppError::Parse(e) }
}
fn port_from_file(path: &str) -> Result<u16, AppError> {
let text = std::fs::read_to_string(path)?;
let port: u16 = text.trim().parse()?;
Ok(port)
}O que isso demonstra:
- O
?converteio::ErroreParseIntErroremAppErrorviaFrom - O caminho feliz permanece linear
- O tipo de retorno deve implementar
Frompara cada fonte de erro
Análise Detalhada
O ? em Result em funções que retornam Result se expande para um match com retorno antecipado. Em main, use fn main() -> Result<(), E>.
try_blocks (onde está estável) agrupa etapas falíveis - verifique a edição.
Armadilhas
?emmainsem tipo de retorno - Erro. Correção:fn main() -> Result<(), Box<dyn Error>>.- Conversão
Fromausente - Erro de compilação. Correção:impl Fromou mapear manualmente. ?emOptionem funçãoResult- Requer tipos compatíveis ouok_or. Correção:ok_or(Error::Missing)?.- Ignorando contexto -
?puro perde a localização. Correção:anyhow::Contextoumap_err. - Usando
?em closures - A closure deve retornarResult. Correção: Alterar o tipo de retorno da closure.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
match | Recuperação complexa por erro | Propagação simples |
map_err | Transformar erro | From já está correto |
unwrap | Apenas para protótipo | Em bibliotecas/produção |
let-else | Guarda de Option | Propagação de Result |
FAQs
Desempenho?
O mesmo que match - custo zero.? em Option?
Apenas em funções que retornam Option.Múltiplos tipos de erro?
Enum customizado + implementações `From`.? async?
Funciona em `async fn` que retornam `Result`.? em closure?
Requer retorno `Result` na closure.Blocos try?
Experimental/estável por versão - verifique a documentação.? em const fn?
Limitado - suporte const crescente.Inspecionar antes do ?
`.inspect_err()` (1.76+) para logar e depois usar ?.anyhow?
Caminho `?` único com `anyhow::Result`.thiserror?
Derivar `From` para erros de biblioteca.Relacionados
- Noções Básicas de Tratamento de Erros
- Tipos de Erro Personalizados
- anyhow
- Contexto e Backtraces de Erro
Versões do Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.