@panic em Zig — Referência e Exemplos

@panic em Zig

O @panic encerra a execução do programa imediatamente com uma mensagem de erro e, em modo debug, um stack trace. É usado para situações irrecuperáveis onde continuar a execução seria inseguro ou impossível. O tipo de retorno é noreturn — o compilador sabe que o fluxo nunca continua após um panic.

Sintaxe

@panic(message: []const u8) noreturn

Parâmetros

  • message ([]const u8): Mensagem de erro exibida ao encerrar o programa.

Valor de retorno

noreturn — a função nunca retorna. O programa é encerrado.

Exemplos práticos

Exemplo 1: Panic em caso de estado inválido

const std = @import("std");

const Estado = enum { ativo, pausado, finalizado };

fn processar(estado: Estado) void {
    switch (estado) {
        .ativo => std.debug.print("Processando...\n", .{}),
        .pausado => std.debug.print("Em pausa.\n", .{}),
        .finalizado => @panic("Tentativa de processar estado finalizado"),
    }
}

pub fn main() void {
    processar(.ativo);
    // processar(.finalizado); // Causaria panic!
}

Exemplo 2: Coerção noreturn em expressões

const std = @import("std");

fn buscarConfig(chave: []const u8) []const u8 {
    const configs = [_]struct { k: []const u8, v: []const u8 }{
        .{ .k = "host", .v = "localhost" },
        .{ .k = "porta", .v = "8080" },
    };

    for (configs) |c| {
        if (std.mem.eql(u8, c.k, chave)) return c.v;
    }

    // @panic tem tipo noreturn, coercível para []const u8
    @panic("Configuração obrigatória não encontrada");
}

pub fn main() void {
    const host = buscarConfig("host");
    std.debug.print("Host: {s}\n", .{host});
}

Exemplo 3: Validação de pré-condições

const std = @import("std");

const MatrizQuadrada = struct {
    dados: []f64,
    tamanho: usize,

    pub fn init(dados: []f64) MatrizQuadrada {
        const n = std.math.sqrt(@as(f64, @floatFromInt(dados.len)));
        const tamanho: usize = @intFromFloat(n);

        if (tamanho * tamanho != dados.len) {
            @panic("Dados não formam uma matriz quadrada");
        }

        return .{ .dados = dados, .tamanho = tamanho };
    }

    pub fn get(self: MatrizQuadrada, linha: usize, coluna: usize) f64 {
        if (linha >= self.tamanho or coluna >= self.tamanho) {
            @panic("Índice fora dos limites da matriz");
        }
        return self.dados[linha * self.tamanho + coluna];
    }
};

Quando usar @panic

  1. Invariantes violados: Quando uma condição que deveria ser impossível ocorre.
  2. Configuração ausente: Recursos obrigatórios que não podem ter fallback.
  3. Bugs: Situações que indicam bug no código, não erro do usuário.
  4. Protótipos: Placeholder temporário para lógica não implementada.

Quando NÃO usar @panic

  • Para erros esperados (use error unions e try/catch).
  • Para validação de entrada do usuário (retorne erro).
  • Para condições que podem ser tratadas graciosamente.

Builtins relacionados

  • @compileError — Erro em tempo de compilação (não runtime)
  • @src — Informações de localização para debugging
  • @compileLog — Debug em tempo de compilação

Tutoriais relacionados

Continue aprendendo Zig

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