@tagName em Zig — Referência e Exemplos

@tagName em Zig

O @tagName retorna o nome do campo ativo de uma tagged union ou o nome de uma variante de enum como string. É fundamental para serialização, logging e depuração de código que trabalha com unions e enums.

Sintaxe

@tagName(valor: anytype) [:0]const u8

O que faz

O @tagName recebe um valor de enum ou tagged union e retorna o nome do campo/variante ativo como uma string constante terminada em sentinela nulo. Para enums, retorna o nome da variante atual. Para tagged unions, retorna o nome do campo ativo.

Parâmetros

  • valor (anytype): Um valor de tipo enum ou tagged union. O tipo deve ter campos nomeados — unions sem tag não são aceitas.

Valor de retorno

Retorna [:0]const u8 — uma string terminada em zero com o nome do campo ou variante ativo.

Exemplos práticos

Exemplo 1: Nome de variantes de enum

const std = @import("std");

const Estacao = enum { primavera, verao, outono, inverno };

test "tag name de enum" {
    const estacao = Estacao.verao;
    const nome = @tagName(estacao);

    try std.testing.expectEqualStrings("verao", nome);

    // Funciona com todas as variantes
    try std.testing.expectEqualStrings("primavera", @tagName(Estacao.primavera));
    try std.testing.expectEqualStrings("inverno", @tagName(Estacao.inverno));
}

Exemplo 2: Serialização de tagged union

const std = @import("std");

const Forma = union(enum) {
    circulo: f64,       // raio
    retangulo: struct { largura: f64, altura: f64 },
    triangulo: struct { base: f64, altura: f64 },
};

fn serializarForma(forma: Forma, writer: anytype) !void {
    try writer.print("{{\"tipo\": \"{s}\"", .{@tagName(forma)});

    switch (forma) {
        .circulo => |raio| {
            try writer.print(", \"raio\": {d}", .{raio});
        },
        .retangulo => |ret| {
            try writer.print(", \"largura\": {d}, \"altura\": {d}", .{
                ret.largura,
                ret.altura,
            });
        },
        .triangulo => |tri| {
            try writer.print(", \"base\": {d}, \"altura\": {d}", .{
                tri.base,
                tri.altura,
            });
        },
    }
    try writer.writeAll("}");
}

test "serializar forma" {
    var buffer: [256]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buffer);
    const writer = stream.writer();

    const forma = Forma{ .circulo = 5.0 };
    try serializarForma(forma, writer);

    const saida = stream.getWritten();
    try std.testing.expectEqualStrings("{\"tipo\": \"circulo\", \"raio\": 5}", saida);
}

Exemplo 3: Logging de eventos com tagged union

const std = @import("std");

const Evento = union(enum) {
    conexao: struct { ip: []const u8, porta: u16 },
    desconexao: struct { motivo: []const u8 },
    mensagem: struct { remetente: []const u8, conteudo: []const u8 },
    erro: struct { codigo: u32, descricao: []const u8 },
};

fn logEvento(evento: Evento) void {
    std.debug.print("[EVENTO:{s}] ", .{@tagName(evento)});

    switch (evento) {
        .conexao => |c| std.debug.print("{s}:{}\n", .{ c.ip, c.porta }),
        .desconexao => |d| std.debug.print("Motivo: {s}\n", .{d.motivo}),
        .mensagem => |m| std.debug.print("De {s}: {s}\n", .{ m.remetente, m.conteudo }),
        .erro => |e| std.debug.print("Código {}: {s}\n", .{ e.codigo, e.descricao }),
    }
}

test "log de eventos" {
    logEvento(.{ .conexao = .{ .ip = "192.168.1.1", .porta = 8080 } });
    logEvento(.{ .mensagem = .{ .remetente = "Alice", .conteudo = "Olá!" } });
    logEvento(.{ .erro = .{ .codigo = 500, .descricao = "Erro interno" } });
}

Casos de uso comuns

  1. Serialização JSON/XML: Usar o nome da tag como chave de tipo ao serializar unions para formatos textuais.
  2. Logging estruturado: Incluir o tipo do evento ou estado em mensagens de log.
  3. Depuração: Imprimir qual variante está ativa durante investigação de bugs.
  4. Métricas e telemetria: Categorizar eventos por tipo usando o nome da tag.
  5. Interface de usuário: Exibir o tipo de um valor union para o usuário em formato legível.

Builtins relacionados

Tutoriais relacionados

Continue aprendendo Zig

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