Orelse em Zig — O que é e Como Usar

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

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

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

Orelse com Return

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

// 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

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

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

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

Orelse vs Catch

OperadorFunciona comPropósito
orelse?T (optional)Valor default para null
catch!T (error union)Tratamento de erro
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

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 — Tipo que pode ser null
  • Catch — Equivalente de orelse para erros
  • Try — Propagação de erros
  • Unreachable — Marcador de código inalcançável

Tutoriais Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.