---
title: "Orelse em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/orelse-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/orelse-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda o operador orelse em Zig: desembrulhe valores opcionais com fallback seguro. Alternativa elegante a if/else para optionals. Guia pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Orelse em Zig — O que é e Como Usar

Entenda o operador orelse em Zig: desembrulhe valores opcionais com fallback seguro. Alternativa elegante a if/else para optionals. Guia pt-BR.


# Orelse em Zig — O que é e Como Usar

## Definição

O operador **`orelse`** em Zig é usado para **desembrulhar (unwrap) valores opcionais** (`?T`), fornecendo um valor alternativo caso o optional seja `null`. É o equivalente ao operador `??` de C# ou ao `?:` de Kotlin — uma forma concisa de dizer "use este valor, ou se for null, use aquele outro".

A sintaxe é: `optional_value orelse fallback`.

## Por que Orelse Importa

1. **Concisão**: Substitui blocos `if/else` verbosos para desembrulhar optionals.
2. **Segurança**: Fornece valor de fallback em vez de panic.
3. **Encadeamento**: Pode ser encadeado e combinado com outras expressões.
4. **Legibilidade**: Expressa a intenção de "valor padrão" de forma clara.

## Exemplo Prático

### Uso Básico

```zig
const std = @import("std");

fn buscarConfiguracao(chave: []const u8) ?u32 {
    if (std.mem.eql(u8, chave, "porta")) return 8080;
    if (std.mem.eql(u8, chave, "timeout")) return 30;
    return null;
}

pub fn main() void {
    const porta = buscarConfiguracao("porta") orelse 3000;
    const max_conn = buscarConfiguracao("max_conexoes") orelse 100;

    std.debug.print("Porta: {}\n", .{porta});       // 8080
    std.debug.print("Max conn: {}\n", .{max_conn});  // 100 (fallback)
}
```

### Orelse com Bloco

```zig
const valor = obterOptional() orelse blk: {
    std.log.warn("Valor não encontrado, usando padrão", .{});
    break :blk valor_padrao;
};
```

### Orelse com Return

```zig
fn processarDados(talvez_dados: ?[]const u8) !void {
    const dados = talvez_dados orelse return error.DadosAusentes;

    // Aqui, dados é []const u8 — desembrulhado
    std.debug.print("Processando {} bytes\n", .{dados.len});
}
```

### Orelse com Unreachable

```zig
// Quando temos CERTEZA que não é null
const lista = [_]u32{ 10, 20, 30 };
const primeiro = std.mem.indexOfScalar(u32, &lista, 10) orelse unreachable;
// primeiro = 0
```

### Encadeando com Operações

```zig
fn encontrarUsuario(id: u32) ?*Usuario {
    // busca no cache ou banco
}

fn nomeDoUsuario(id: u32) []const u8 {
    const usuario = encontrarUsuario(id) orelse return "Desconhecido";
    return usuario.nome;
}
```

### Comparação: orelse vs if

```zig
// Com orelse (conciso)
const resultado = obterValor() orelse 0;

// Equivalente com if (verboso)
const resultado2 = if (obterValor()) |v| v else 0;
```

## Orelse vs Catch

| Operador | Funciona com | Propósito |
|----------|-------------|-----------|
| `orelse` | `?T` (optional) | Valor default para null |
| `catch` | `!T` (error union) | Tratamento de erro |

```zig
const opt: ?u32 = null;
const a = opt orelse 42;          // orelse com optional

const err: anyerror!u32 = error.Falha;
const b = err catch 42;           // catch com error union
```

## Casos de Uso Comuns

O `orelse` aparece naturalmente em situações de busca, configuração e parsing:

```zig
const std = @import("std");

// Leitura de variável de ambiente com padrão
fn porta() u16 {
    const env = std.posix.getenv("PORT") orelse return 8080;
    return std.fmt.parseInt(u16, env, 10) catch 8080;
}

// Busca em slice com padrão
fn encontrarPosicao(haystack: []const u32, needle: u32) usize {
    return std.mem.indexOfScalar(u32, haystack, needle) orelse haystack.len;
}

// Acesso a mapa com fallback
fn obterConfig(mapa: std.StringHashMap([]const u8), chave: []const u8) []const u8 {
    return mapa.get(chave) orelse "valor_padrão";
}
```

## Orelse em Encadeamentos

Um padrão poderoso é encadear múltiplos `orelse` para tentar fontes alternativas:

```zig
fn obterToken(env: ?[]const u8, arquivo: ?[]const u8, padrao: []const u8) []const u8 {
    return env orelse arquivo orelse padrao;
}
```

Neste exemplo, `env` é tentado primeiro. Se for null, tenta `arquivo`. Se também for null, usa `padrao`. O encadeamento é avaliado da esquerda para a direita e para no primeiro valor não-null.

## Comparação com Outras Linguagens

| Linguagem | Operador equivalente | Observação |
|-----------|---------------------|-----------|
| Zig | `orelse` | Apenas para `?T` |
| Kotlin | `?: ` (Elvis) | Para tipos anuláveis |
| C# | `??` | Para tipos anuláveis |
| Swift | `??` | Para `Optional<T>` |
| Rust | `.unwrap_or(v)` | Método em `Option<T>` |
| JavaScript | `??` | Nullish coalescing |

A diferença fundamental do Zig é que `orelse` é verificado em tempo de compilação — você não pode usar `orelse` em um `!T` (error union) por engano; o compilador rejeita imediatamente.

## Armadilhas Comuns

- **Confundir com `catch`**: `orelse` é para optionals (`?T`); `catch` é para error unions (`!T`). Usar o errado causa erro de compilação.
- **Orelse com unreachable irresponsável**: `orelse unreachable` causa panic se o valor for null. Só use quando tiver certeza absoluta.
- **Efeitos colaterais no fallback**: O fallback do `orelse` só é avaliado se o optional for null (avaliação preguiçosa). Não dependa dele para efeitos colaterais obrigatórios.
- **Esquecer que orelse desembrulha**: Após `orelse`, o tipo é `T`, não `?T`. O optional já foi resolvido.

## Termos Relacionados

- [Optional](/glossario/optional/) — Tipo que pode ser null
- [Catch](/glossario/catch/) — Equivalente de orelse para erros
- [Try](/glossario/try/) — Propagação de erros
- [Unreachable](/glossario/unreachable/) — Marcador de código inalcançável

## Tutoriais Relacionados

- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
- [Tratamento de Erros em Zig](/tutoriais/tratamento-de-erros-em-zig/)
