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
- Concisão: Substitui blocos
if/elseverbosos para desembrulhar optionals. - Segurança: Fornece valor de fallback em vez de panic.
- Encadeamento: Pode ser encadeado e combinado com outras expressões.
- 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
| Operador | Funciona com | Propó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
Casos de Uso Comuns
O orelse aparece naturalmente em situações de busca, configuração e parsing:
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:
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 unreachablecausa panic se o valor for null. Só use quando tiver certeza absoluta. - Efeitos colaterais no fallback: O fallback do
orelsesó é 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