---
title: "Panic em unwrap(): Como Evitar no Rust"
url: "https://rustlang.com.br/erros/panic-unwrap/"
markdown_url: "https://rustlang.com.br/erros/panic-unwrap.MD"
description: "Como evitar panics causados por unwrap() em Option e Result no Rust. Aprenda alternativas seguras como match, if let, unwrap_or, map e o operador ? para tratamento de erros."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Panic em unwrap(): Como Evitar no Rust

Como evitar panics causados por unwrap() em Option e Result no Rust. Aprenda alternativas seguras como match, if let, unwrap_or, map e o operador ? para tratamento de erros.


# Panic em unwrap(): Como Evitar

O **panic por `unwrap()`** é provavelmente o erro de runtime mais comum no Rust. Ele ocorre quando você chama `.unwrap()` em um `Option::None` ou `Result::Err`. Diferente dos erros de compilação, esse problema só aparece durante a execução do programa.

## A Mensagem de Erro

```
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:5:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

Para `Result`:

```
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:
Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:3:47
```

## O Que Significa

`Option<T>` e `Result<T, E>` são os tipos do Rust para representar valores que podem estar ausentes ou operações que podem falhar:

- `Option<T>` pode ser `Some(valor)` ou `None`
- `Result<T, E>` pode ser `Ok(valor)` ou `Err(erro)`

O método `.unwrap()` extrai o valor interno, mas **entra em panic** se não houver valor. É como dizer "tenho certeza absoluta que há um valor aqui" — e se não houver, o programa aborta.

Usar `unwrap()` em produção é geralmente um erro. É aceitável em protótipos, testes e situações onde você tem certeza lógica de que o valor existe, mas mesmo assim há alternativas melhores.

## Código com Erro

```rust
fn main() {
    let numeros = vec![1, 2, 3];

    // PANIC: índice 10 não existe, get() retorna None
    let valor = numeros.get(10).unwrap();

    // PANIC: arquivo pode não existir
    let conteudo = std::fs::read_to_string("inexistente.txt").unwrap();

    // PANIC: parse pode falhar
    let numero: i32 = "abc".parse().unwrap();
}
```

## Como Resolver

### Solução 1: Usar `match` para Tratamento Explícito

O tratamento mais completo e explícito:

```rust
fn main() {
    let numeros = vec![1, 2, 3];

    match numeros.get(10) {
        Some(valor) => println!("Valor: {}", valor),
        None => println!("Índice fora dos limites"),
    }

    match std::fs::read_to_string("config.txt") {
        Ok(conteudo) => println!("Conteúdo: {}", conteudo),
        Err(erro) => eprintln!("Erro ao ler arquivo: {}", erro),
    }
}
```

### Solução 2: Usar `if let` para Casos Simples

Quando você só se importa com o caso de sucesso:

```rust
fn main() {
    let numeros = vec![1, 2, 3];

    if let Some(valor) = numeros.get(0) {
        println!("Primeiro: {}", valor);
    }

    if let Ok(conteudo) = std::fs::read_to_string("config.txt") {
        println!("Conteúdo: {}", conteudo);
    } else {
        println!("Usando configuração padrão");
    }
}
```

### Solução 3: Usar `unwrap_or` e Variantes

Forneça um valor padrão em vez de entrar em panic:

```rust
fn main() {
    let numeros = vec![1, 2, 3];

    // Valor padrão fixo
    let valor = numeros.get(10).unwrap_or(&0);
    println!("Valor: {}", valor);

    // Valor padrão calculado (lazy — só executa se necessário)
    let valor = numeros.get(10).unwrap_or_else(|| {
        println!("Usando padrão");
        &0
    });

    // Para Result:
    let conteudo = std::fs::read_to_string("config.txt")
        .unwrap_or_else(|_| String::from("configuração padrão"));

    // unwrap_or_default — usa Default::default()
    let numero: i32 = "abc".parse().unwrap_or_default(); // 0
}
```

### Solução 4: Usar o Operador `?` (Propagação de Erros)

O operador `?` é a forma idiomática do Rust para propagar erros:

```rust
use std::fs;
use std::io;

fn ler_configuracao() -> Result<String, io::Error> {
    let conteudo = fs::read_to_string("config.txt")?;  // Propaga o erro
    Ok(conteudo.trim().to_string())
}

fn obter_porta() -> Result<u16, Box<dyn std::error::Error>> {
    let config = ler_configuracao()?;
    let porta: u16 = config.parse()?;  // ? também funciona com outros erros
    Ok(porta)
}

fn main() {
    match obter_porta() {
        Ok(porta) => println!("Porta: {}", porta),
        Err(e) => eprintln!("Erro: {}", e),
    }
}
```

O `?` pode ser usado em funções que retornam `Result` ou `Option`. Ele "desempacota" o valor de sucesso ou retorna o erro imediatamente.

### Solução 5: Usar `map`, `and_then` e Combinadores

Encadeie operações de forma funcional:

```rust
fn main() {
    let input = "42";

    // map transforma o valor interno
    let resultado: Option<i32> = input.parse::<i32>().ok().map(|n| n * 2);
    println!("{:?}", resultado); // Some(84)

    // and_then encadeia operações que retornam Option/Result
    let valor = Some("42")
        .and_then(|s| s.parse::<i32>().ok())
        .map(|n| n + 10)
        .unwrap_or(0);
    println!("{}", valor); // 52

    // filter descarta valores que não atendem a condição
    let positivo = Some(-5_i32).filter(|n| *n > 0);
    println!("{:?}", positivo); // None
}
```

### Solução 6: Usar `expect()` com Mensagem Clara

Se você precisa de unwrap (em testes ou situações seguras), use `expect()` com uma mensagem explicativa:

```rust
fn main() {
    let porta: u16 = std::env::var("PORT")
        .expect("Variável PORT deve estar definida")
        .parse()
        .expect("PORT deve ser um número válido");
}
```

`expect()` entra em panic como `unwrap()`, mas com uma mensagem customizada que facilita a depuração.

## Quando unwrap() é Aceitável

| Situação | Aceitável? |
|---|---|
| Testes (`#[test]`) | Sim |
| Exemplos e protótipos | Sim |
| Valor garantido pela lógica | Sim, mas prefira `expect()` |
| Código de produção | Nao — use `?`, `match` ou combinadores |
| Input do usuário | Nunca |

## Veja Também

- [Panic: Index Out of Bounds](/erros/panic-index-out-of-bounds/)
- [Panic: Stack Overflow](/erros/panic-stack-overflow/)
- [Tutorial de Tratamento de Erros](/tutoriais/tratamento-de-erros/)
- [E0308: Tipos Incompatíveis](/erros/e0308-tipos-incompativeis/)
- [Cheatsheet Rust](/cheatsheet/)
