@enumFromInt em Zig — Referência e Exemplos

@enumFromInt em Zig

O @enumFromInt cria um valor enum a partir de um valor inteiro. É a operação inversa de @intFromEnum. Este builtin é especialmente útil ao deserializar dados, processar protocolos de rede ou interagir com código C que usa constantes inteiras no lugar de enums.

Sintaxe

@enumFromInt(valor: IntType) EnumType

O tipo enum de retorno é inferido pelo contexto.

O que faz

O @enumFromInt recebe um valor inteiro e o converte para a variante correspondente de um tipo enum. Se o valor inteiro não corresponder a nenhuma variante definida no enum, o comportamento é ilegal e será detectado como erro em modo debug (safety-checked).

Parâmetros

  • valor (IntType): O valor inteiro a ser convertido para enum. O tipo deve ser compatível com o tipo de tag do enum de destino.

Valor de retorno

Retorna o valor enum correspondente ao inteiro fornecido.

Exemplos práticos

Exemplo 1: Conversão básica

const std = @import("std");

const Cor = enum { vermelho, verde, azul };

test "conversão inteiro para enum" {
    const cor: Cor = @enumFromInt(0);
    try std.testing.expect(cor == .vermelho);

    const outra: Cor = @enumFromInt(2);
    try std.testing.expect(outra == .azul);
}

Exemplo 2: Deserialização de protocolo

const std = @import("std");

const TipoMensagem = enum(u8) {
    ping = 1,
    pong = 2,
    dados = 3,
    erro = 4,
    desconexao = 5,
};

const Mensagem = struct {
    tipo: TipoMensagem,
    payload: []const u8,
};

fn parsearMensagem(buffer: []const u8) !Mensagem {
    if (buffer.len < 2) return error.MensagemMuitoCurta;

    const byte_tipo = buffer[0];
    if (byte_tipo < 1 or byte_tipo > 5) return error.TipoInvalido;

    const tipo: TipoMensagem = @enumFromInt(byte_tipo);
    const tamanho_payload = buffer[1];

    if (buffer.len < 2 + tamanho_payload) return error.PayloadIncompleto;

    return .{
        .tipo = tipo,
        .payload = buffer[2 .. 2 + tamanho_payload],
    };
}

test "parsear mensagem" {
    const buffer = [_]u8{ 1, 3, 'a', 'b', 'c' };
    const msg = try parsearMensagem(&buffer);
    try std.testing.expect(msg.tipo == .ping);
    try std.testing.expectEqualStrings("abc", msg.payload);
}

Exemplo 3: Iteração sobre todos os valores de um enum

const std = @import("std");

const DiaSemana = enum(u8) {
    segunda = 0,
    terca = 1,
    quarta = 2,
    quinta = 3,
    sexta = 4,
    sabado = 5,
    domingo = 6,
};

fn nomeDodia(dia: DiaSemana) []const u8 {
    return switch (dia) {
        .segunda => "Segunda-feira",
        .terca => "Terça-feira",
        .quarta => "Quarta-feira",
        .quinta => "Quinta-feira",
        .sexta => "Sexta-feira",
        .sabado => "Sábado",
        .domingo => "Domingo",
    };
}

test "iterar sobre dias da semana" {
    // Usar @enumFromInt para iterar por todos os valores possíveis
    var i: u8 = 0;
    while (i <= 6) : (i += 1) {
        const dia: DiaSemana = @enumFromInt(i);
        const nome = nomeDodia(dia);
        std.debug.print("Dia {}: {s}\n", .{ i, nome });
    }
}

Casos de uso comuns

  1. Deserialização: Converter bytes recebidos de rede, arquivo ou API para valores enum tipados.
  2. Interoperabilidade com C: Converter constantes inteiras retornadas por funções C para enums Zig mais seguros.
  3. Iteração: Percorrer todos os valores possíveis de um enum usando um loop numérico.
  4. Tabelas de lookup: Converter índices de array para valores enum correspondentes.
  5. Protocolos binários: Parsear cabeçalhos de protocolo que usam códigos numéricos.

Cuidados importantes

  • Se o valor inteiro não corresponder a nenhuma variante válida do enum, o comportamento é ilegal. Em modo debug, isso causa um panic. Em modo release, o comportamento pode ser indefinido.
  • Sempre valide o valor inteiro antes de chamar @enumFromInt quando os dados vêm de fontes externas não confiáveis.

Builtins relacionados

  • @intFromEnum — Operação inversa: obtém inteiro do enum
  • @tagName — Obtém o nome da variante como string
  • @typeInfo — Inspeciona as variantes de um enum
  • @errorName — Obtém o nome de um erro

Tutoriais relacionados

Continue aprendendo Zig

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