undeclared identifier — Como Resolver em Zig
O Que Este Erro Significa
O erro undeclared identifier aparece quando você tenta usar um nome (variável, constante, função ou tipo) que o compilador não consegue encontrar no escopo atual. Isso significa que o nome não foi declarado anteriormente, foi digitado incorretamente, ou está em um escopo diferente do que você espera.
A mensagem completa é:
error: use of undeclared identifier 'nome'
Causas Comuns
1. Erro de Digitação no Nome
A causa mais trivial, mas surpreendentemente frequente:
const std = @import("std");
pub fn main() void {
const mensagem = "Olá";
std.debug.print("{s}\n", .{mesagem}); // ERRO: 'mesagem' (faltou o 'n')
}
2. Variável Fora de Escopo
Em Zig, variáveis declaradas dentro de um bloco não existem fora dele:
const std = @import("std");
pub fn main() void {
if (true) {
const x: u32 = 42;
_ = x;
}
std.debug.print("{}\n", .{x}); // ERRO: 'x' não existe neste escopo
}
3. Esquecer de Importar o Módulo
pub fn main() void {
std.debug.print("olá\n", .{}); // ERRO: 'std' não declarado
}
Faltou a linha de import:
const std = @import("std"); // Necessário!
4. Usar Função Antes de Declará-la (em Escopo Local)
Diferente de funções no nível do módulo, variáveis locais precisam ser declaradas antes do uso:
pub fn main() void {
const resultado = calcular(5); // ERRO: se 'calcular' não está no escopo do módulo
_ = resultado;
}
Note que funções declaradas no nível do arquivo (fora de qualquer função) podem ser chamadas de qualquer lugar do mesmo arquivo, independente da ordem.
5. Acessar Campo de Struct Incorretamente
const Ponto = struct {
x: f64,
y: f64,
};
pub fn main() void {
const p = Ponto{ .x = 1.0, .y = 2.0 };
_ = p.z; // ERRO: pode gerar um erro de campo, não de identificador
}
6. Confundir Namespace de Enum
const Cor = enum { vermelho, verde, azul };
pub fn main() void {
const c = vermelho; // ERRO: 'vermelho' não é um identificador global
_ = c;
}
7. Usar Variável de Captura Fora do Bloco
const std = @import("std");
pub fn main() void {
const opcional: ?u32 = 42;
if (opcional) |valor| {
std.debug.print("{}\n", .{valor});
}
std.debug.print("{}\n", .{valor}); // ERRO: 'valor' só existe dentro do if
}
Como Corrigir
Solução 1: Verificar a Ortografia
Compare cuidadosamente o nome usado com o nome declarado:
const std = @import("std");
pub fn main() void {
const mensagem = "Olá";
std.debug.print("{s}\n", .{mensagem}); // Corrigido: 'mensagem'
}
Solução 2: Declarar no Escopo Correto
Mova a declaração para um escopo onde ela seja acessível:
const std = @import("std");
pub fn main() void {
var x: u32 = 0;
if (true) {
x = 42;
}
std.debug.print("{}\n", .{x}); // OK: 'x' está no escopo de main
}
Solução 3: Adicionar os Imports Necessários
const std = @import("std"); // Sempre importe o que usar
pub fn main() void {
std.debug.print("olá\n", .{});
}
Solução 4: Usar o Namespace Completo para Enums
const Cor = enum { vermelho, verde, azul };
pub fn main() void {
const c = Cor.vermelho; // Correto: usa o namespace da enum
_ = c;
}
Ou use com anotação de tipo:
const c: Cor = .vermelho; // Também funciona com tipo inferido
Solução 5: Ampliar o Escopo da Variável de Captura
const std = @import("std");
pub fn main() void {
const opcional: ?u32 = 42;
const valor = opcional orelse 0; // Valor acessível em todo o escopo
std.debug.print("{}\n", .{valor});
}
Cenários Especiais
Identificadores em @import de Outros Arquivos
Quando você importa um módulo, só tem acesso a declarações pub:
// arquivo: utils.zig
fn funcaoPrivada() void {} // Sem 'pub' — não acessível externamente
pub fn funcaoPublica() void {} // Com 'pub' — acessível
// arquivo: main.zig
const utils = @import("utils.zig");
pub fn main() void {
utils.funcaoPublica(); // OK
utils.funcaoPrivada(); // ERRO: não é público
}
Builtin Functions
Funções built-in do Zig começam com @. Se você esquecer o @, terá um erro de identificador:
const tipo = TypeOf(variavel); // ERRO
const tipo = @TypeOf(variavel); // Correto
Dicas Importantes
- Use ZLS (Zig Language Server) — Autocomplete previne erros de digitação
- Organize imports no topo — Mantenha todos os
@importno início do arquivo - Preste atenção no escopo — Chaves
{}criam novos escopos em Zig - Funções no nível do módulo — São acessíveis em qualquer ordem no mesmo arquivo
Erros Relacionados
- unused local variable — Variável declarada mas não usada (o oposto)
- shadows declaration from outer scope — Nome duplicado em escopos aninhados
- ambiguous reference — Referência ambígua entre imports