@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
- Deserialização: Converter bytes recebidos de rede, arquivo ou API para valores enum tipados.
- Interoperabilidade com C: Converter constantes inteiras retornadas por funções C para enums Zig mais seguros.
- Iteração: Percorrer todos os valores possíveis de um enum usando um loop numérico.
- Tabelas de lookup: Converter índices de array para valores enum correspondentes.
- 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
@enumFromIntquando 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