---
title: "@intFromEnum em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@intfromenum-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@intfromenum-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @intFromEnum em Zig. Aprenda a obter o valor inteiro subjacente de enums com exemplos práticos."
date: "2026-02-21"
author: "Zig Brasil"
---

# @intFromEnum em Zig — Referência e Exemplos

Referência completa do @intFromEnum em Zig. Aprenda a obter o valor inteiro subjacente de enums com exemplos práticos.


# @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

```zig
@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

```zig
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

```zig
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

```zig
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

1. **Serialização**: Converter valores enum para inteiros para transmitir via rede, salvar em arquivo ou enviar para APIs C.
2. **Operações bit a bit**: Usar valores de enum como flags combinados com operações OR, AND, XOR.
3. **Indexação de arrays**: Usar o valor do enum como índice em um array de lookup.
4. **Protocolos de comunicação**: Converter enums para códigos numéricos de protocolo (como HTTP status codes).
5. **Interoperabilidade com C**: Converter enums Zig para valores inteiros esperados por funções C.

```zig
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;
}
```

## Tipo de tag do enum

O tipo inteiro usado internamente pelo enum pode ser especificado explicitamente ou inferido pelo compilador. Quando não especificado, o Zig escolhe o menor tipo inteiro capaz de representar todas as variantes:

```zig
const Pequeno = enum { a, b, c }; // tipo de tag inferido: u2 (cabe 0, 1, 2)
const Grande = enum(u32) { x = 0, y = 1_000_000 }; // tipo explícito: u32

const tag_pequeno = @intFromEnum(Pequeno.b); // tipo: u2
const tag_grande = @intFromEnum(Grande.y);   // tipo: u32
```

Para verificar o tipo de tag de um enum em comptime, use `@typeInfo`:

```zig
const TagType = @typeInfo(Pequeno).@"enum".tag_type; // u2
```

## Comparação com C equivalente

Em C, enums são implicitamente inteiros, e a conversão ocorre automaticamente — o que pode esconder bugs:

```c
typedef enum { OK = 200, NAO_ENCONTRADO = 404 } Status;
int codigo = NAO_ENCONTRADO; // conversão implícita, sem aviso
```

Em Zig, a conversão deve ser explícita, deixando a intenção clara:

```zig
const Status = enum(u16) { ok = 200, nao_encontrado = 404 };
const codigo: u16 = @intFromEnum(.nao_encontrado); // explícito e seguro
```

Além disso, em Zig o tipo de tag é sempre bem definido e consistente entre plataformas, enquanto em C o tamanho de um enum pode variar entre compiladores e plataformas.

## Erros comuns

**Erro 1: Assumir que todos os enums começam em zero.**

```zig
const Status = enum(u16) { ok = 200, erro = 500 };
// @intFromEnum(.ok) == 200, não 0!
// Não use o resultado como índice de array diretamente.
```

**Erro 2: Armazenar o valor inteiro em um tipo menor que o tipo de tag.**

```zig
const Grande = enum(u32) { max = 1_000_000 };
const val: u8 = @intFromEnum(Grande.max); // Overflow silencioso ou erro de compilação!
```

Sempre armazene o resultado em um tipo compatível com o tipo de tag do enum.

## Perguntas Frequentes

**P: Posso usar `@intFromEnum` com enums não exaustivos (com `_`)?**

Sim. Enums não exaustivos aceitam valores arbitrários do tipo de tag, e `@intFromEnum` retorna o valor inteiro correspondente, seja ele uma variante nomeada ou não.

**P: `@intFromEnum` funciona em comptime?**

Sim. Se o valor do enum for conhecido em tempo de compilação, o resultado também é comptime. Isso é útil para calcular tamanhos de arrays e outros valores comptime baseados em variantes de enum.

**P: Como obter o número total de variantes de um enum?**

Use `@typeInfo` para acessar a lista de campos do enum:

```zig
const num_variantes = @typeInfo(DiaSemana).@"enum".fields.len;
```

## Builtins relacionados

- [@enumFromInt](/builtins/enum-from-int/) — Operação inversa: cria enum a partir de inteiro
- [@tagName](/builtins/tag-name/) — Obtém o nome da variante como string
- [@intFromBool](/builtins/int-from-bool/) — Converte booleano para inteiro
- [@typeInfo](/builtins/type-info/) — Inspeciona a definição do enum

## Tutoriais relacionados

- [Enums em Zig](/tutoriais/enums/)
- [Sistema de tipos do Zig](/tutoriais/tipos/)
- [Interoperabilidade com C](/tutoriais/interop-c/)
