@intFromEnum em Zig
O @intFromEnum extrai o valor inteiro subjacente (tag value) de um valor enum. Todo enum em Zig possui internamente um tipo inteiro que representa cada variante, e este builtin permite acessar esse valor numérico diretamente.
Sintaxe
@intFromEnum(valor: anytype) TagType
O que faz
O @intFromEnum recebe um valor de tipo enum e retorna o valor inteiro correspondente à tag daquela variante. Por padrão, os valores são atribuídos sequencialmente começando em zero, mas podem ser personalizados na declaração do enum.
Parâmetros
- valor (
anytype): Um valor de tipo enum. Deve ser uma instância de um tipo enum válido.
Valor de retorno
Retorna o valor inteiro da tag do enum. O tipo do inteiro retornado corresponde ao tipo de tag do enum (que pode ser especificado explicitamente ou inferido pelo compilador).
Exemplos práticos
Exemplo 1: Obtendo valores de enum padrão
const std = @import("std");
const Direcao = enum { norte, sul, leste, oeste };
test "valores padrão de enum" {
// Por padrão, enums são numerados sequencialmente a partir de 0
try std.testing.expect(@intFromEnum(Direcao.norte) == 0);
try std.testing.expect(@intFromEnum(Direcao.sul) == 1);
try std.testing.expect(@intFromEnum(Direcao.leste) == 2);
try std.testing.expect(@intFromEnum(Direcao.oeste) == 3);
}
Exemplo 2: Enum com valores personalizados
const std = @import("std");
const HttpStatus = enum(u16) {
ok = 200,
criado = 201,
nao_encontrado = 404,
erro_interno = 500,
nao_implementado = 501,
};
fn statusParaString(status: HttpStatus) []const u8 {
return switch (status) {
.ok => "OK",
.criado => "Criado",
.nao_encontrado => "Não Encontrado",
.erro_interno => "Erro Interno do Servidor",
.nao_implementado => "Não Implementado",
};
}
test "HTTP status codes" {
const status = HttpStatus.nao_encontrado;
const codigo: u16 = @intFromEnum(status);
try std.testing.expect(codigo == 404);
try std.testing.expectEqualStrings("Não Encontrado", statusParaString(status));
// Útil para serialização ou comunicação via rede
const ok_code: u16 = @intFromEnum(HttpStatus.ok);
try std.testing.expect(ok_code == 200);
}
Exemplo 3: Flags com enum e operações bit a bit
const std = @import("std");
const Permissao = enum(u8) {
leitura = 0b001,
escrita = 0b010,
execucao = 0b100,
};
fn temPermissao(mascara: u8, perm: Permissao) bool {
return (mascara & @intFromEnum(perm)) != 0;
}
fn combinarPermissoes(perms: []const Permissao) u8 {
var resultado: u8 = 0;
for (perms) |p| {
resultado |= @intFromEnum(p);
}
return resultado;
}
test "verificar permissões" {
const perms = [_]Permissao{ .leitura, .escrita };
const mascara = combinarPermissoes(&perms);
try std.testing.expect(mascara == 0b011);
try std.testing.expect(temPermissao(mascara, .leitura));
try std.testing.expect(temPermissao(mascara, .escrita));
try std.testing.expect(!temPermissao(mascara, .execucao));
}
Casos de uso comuns
- Serialização: Converter valores enum para inteiros para transmitir via rede, salvar em arquivo ou enviar para APIs C.
- Operações bit a bit: Usar valores de enum como flags combinados com operações OR, AND, XOR.
- Indexação de arrays: Usar o valor do enum como índice em um array de lookup.
- Protocolos de comunicação: Converter enums para códigos numéricos de protocolo (como HTTP status codes).
- Interoperabilidade com C: Converter enums Zig para valores inteiros esperados por funções C.
const NivelLog = enum(u8) { debug = 0, info = 1, warn = 2, err = 3 };
var contadores: [4]u64 = .{ 0, 0, 0, 0 };
fn incrementarContador(nivel: NivelLog) void {
contadores[@intFromEnum(nivel)] += 1;
}
Builtins relacionados
- @enumFromInt — Operação inversa: cria enum a partir de inteiro
- @tagName — Obtém o nome da variante como string
- @intFromBool — Converte booleano para inteiro
- @typeInfo — Inspeciona a definição do enum