---
title: "@field em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@field-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@field-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @field em Zig. Aprenda a acessar campos de structs por nome dinâmico em comptime com exemplos práticos."
date: "2026-02-21"
author: "Zig Brasil"
---

# @field em Zig — Referência e Exemplos

Referência completa do @field em Zig. Aprenda a acessar campos de structs por nome dinâmico em comptime com exemplos práticos.


# @field em Zig

O `@field` permite acessar campos de structs, unions e enums usando um nome de campo determinado em tempo de compilação (comptime). Isso é fundamental para metaprogramação, pois permite iterar sobre campos e acessá-los dinamicamente sem escrever código para cada campo individualmente.

## Sintaxe

```zig
@field(objeto: anytype, comptime nome_campo: []const u8) FieldType
```

## O que faz

O `@field` acessa o valor de um campo específico de uma struct, union ou enum usando uma string com o nome do campo. Embora o nome seja uma string, ele deve ser conhecido em tempo de compilação (`comptime`), o que permite ao compilador verificar a existência do campo e resolver seu tipo estaticamente.

## Parâmetros

- **objeto** (`anytype`): A instância da struct, union ou enum cujo campo será acessado. Pode ser um valor ou um ponteiro.
- **nome_campo** (`[]const u8`, comptime): O nome do campo como string literal ou valor comptime. Deve corresponder a um campo existente no tipo.

## Valor de retorno

Retorna o valor do campo especificado. O tipo retornado é o tipo declarado para aquele campo na definição da struct/union.

## Exemplos práticos

### Exemplo 1: Acesso dinâmico a campos

```zig
const std = @import("std");

const Pessoa = struct {
    nome: []const u8,
    idade: u32,
    email: []const u8,
};

test "acesso dinâmico a campos" {
    const pessoa = Pessoa{
        .nome = "Maria",
        .idade = 30,
        .email = "maria@exemplo.com",
    };

    // Acessar campos por nome
    try std.testing.expectEqualStrings("Maria", @field(pessoa, "nome"));
    try std.testing.expect(@field(pessoa, "idade") == 30);
    try std.testing.expectEqualStrings("maria@exemplo.com", @field(pessoa, "email"));
}
```

### Exemplo 2: Serialização genérica iterando sobre campos

```zig
const std = @import("std");

fn toQueryString(comptime T: type, valor: T) ![]u8 {
    var buffer: [1024]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buffer);
    const writer = stream.writer();

    const fields = @typeInfo(T).@"struct".fields;
    inline for (fields, 0..) |campo, i| {
        if (i > 0) try writer.writeByte('&');

        const campo_valor = @field(valor, campo.name);
        try writer.print("{s}=", .{campo.name});

        if (@TypeOf(campo_valor) == []const u8) {
            try writer.writeAll(campo_valor);
        } else {
            try writer.print("{}", .{campo_valor});
        }
    }

    return stream.getWritten();
}

const Filtro = struct {
    pagina: u32,
    limite: u32,
    ordem: []const u8,
};

test "query string genérica" {
    const filtro = Filtro{
        .pagina = 1,
        .limite = 20,
        .ordem = "nome",
    };

    const qs = try toQueryString(Filtro, filtro);
    // Resultado: "pagina=1&limite=20&ordem=nome"
    try std.testing.expectEqualStrings("pagina=1&limite=20&ordem=nome", qs);
}
```

### Exemplo 3: Comparação genérica de structs

```zig
const std = @import("std");

fn structsIguais(comptime T: type, a: T, b: T) bool {
    const fields = @typeInfo(T).@"struct".fields;
    inline for (fields) |campo| {
        const val_a = @field(a, campo.name);
        const val_b = @field(b, campo.name);

        if (campo.type == []const u8) {
            if (!std.mem.eql(u8, val_a, val_b)) return false;
        } else {
            if (val_a != val_b) return false;
        }
    }
    return true;
}

const Coordenada = struct {
    x: i32,
    y: i32,
    z: i32,
};

test "comparação genérica" {
    const a = Coordenada{ .x = 1, .y = 2, .z = 3 };
    const b = Coordenada{ .x = 1, .y = 2, .z = 3 };
    const c = Coordenada{ .x = 1, .y = 2, .z = 4 };

    try std.testing.expect(structsIguais(Coordenada, a, b));
    try std.testing.expect(!structsIguais(Coordenada, a, c));
}
```

## Casos de uso comuns

1. **Serialização/Deserialização**: Iterar sobre campos de structs para converter automaticamente para JSON, CSV, query strings, etc.
2. **ORM e mapeamento de dados**: Mapear colunas de banco de dados para campos de struct dinamicamente.
3. **Validação genérica**: Verificar valores de todos os campos de uma struct de forma genérica.
4. **Comparação e hash**: Implementar igualdade e hash para structs arbitrárias.
5. **Clonagem de structs**: Copiar seletivamente campos entre structs de tipos diferentes.

## Como funciona internamente

O `@field` é uma operação puramente de tempo de compilação. Quando o compilador encontra `@field(obj, "nome")`, ele resolve o campo correspondente e gera o mesmo código de acesso que seria gerado por `obj.nome`. Não há overhead em runtime — a string é usada apenas durante a compilação para encontrar o campo correto.

Isso significa que `@field(obj, "nome")` e `obj.nome` são **equivalentes em termos de desempenho**. A diferença é que o nome em `@field` pode vir de um valor comptime calculado, enquanto `.nome` é sempre literal.

## Comparação com reflexão em outras linguagens

Em linguagens como Java ou Python, a reflexão ocorre em runtime e tem custo:

```python
# Python — reflexão em runtime, com overhead
valor = getattr(obj, nome_campo)  # busca em dicionário interno
```

Em Zig, `@field` é resolvido em tempo de compilação — o compilador sabe exatamente qual campo acessar antes do programa rodar:

```zig
// Zig — resolvido em comptime, sem overhead em runtime
const valor = @field(obj, nome_campo); // equivale a obj.nome_campo
```

Essa abordagem oferece a conveniência da reflexão sem o custo de desempenho das implementações tradicionais.

## Erros comuns

**Erro 1: Tentar usar `@field` com um nome dinâmico (runtime).**

```zig
// ERRADO — nome deve ser comptime
const nome: []const u8 = lerNomeDoBancoDeDados(); // valor em runtime
const valor = @field(minha_struct, nome); // erro de compilação!
```

O nome do campo **deve** ser conhecido em tempo de compilação. Para acesso verdadeiramente dinâmico, é necessário um switch ou um sistema de dispatch manual.

**Erro 2: Acessar campo inexistente sem verificar com `@hasField`.**

```zig
// Perigoso sem verificação prévia
const valor = @field(obj, "campo_que_pode_nao_existir"); // erro de compilação se não existir

// Correto — verificar antes
if (@hasField(@TypeOf(obj), "campo_que_pode_nao_existir")) {
    const valor = @field(obj, "campo_que_pode_nao_existir");
}
```

## Perguntas Frequentes

**P: `@field` pode ser usado para modificar campos (lvalue)?**

Sim. Se o objeto for mutável (não `const`), `@field` pode ser usado como destino de atribuição:

```zig
var pessoa = Pessoa{ .nome = "Ana", .idade = 25, .email = "a@b.com" };
@field(pessoa, "idade") = 26; // equivale a pessoa.idade = 26
```

**P: Funciona com unions e enums, além de structs?**

Sim. `@field` funciona com qualquer tipo que tenha campos nomeados: structs, unions e enums com fields. Para unions, o campo deve ser o campo ativo no momento do acesso.

**P: Há diferença entre `@field(obj, "x")` e `obj.x`?**

Em termos de código gerado, nenhuma diferença. A utilidade do `@field` está em quando o nome do campo é uma variável comptime, como o `campo.name` iterado com `inline for` sobre `@typeInfo(T).@"struct".fields`.

## Builtins relacionados

- [@hasField](/builtins/has-field/) — Verifica se um tipo possui determinado campo antes de acessá-lo
- [@typeInfo](/builtins/type-info/) — Lista todos os campos de um tipo
- [@hasDecl](/builtins/has-decl/) — Verifica existência de declarações (funções, constantes)
- [@typeName](/builtins/type-name/) — Obtém nome do tipo para mensagens de erro

## Tutoriais relacionados

- [Metaprogramação com comptime](/tutoriais/comptime/)
- [Programação genérica em Zig](/tutoriais/generics/)
- [Serialização em Zig](/tutoriais/serializacao/)
