cannot assign to constant — Como Resolver em Zig
O Que Este Erro Significa
O erro cannot assign to constant ocorre quando você tenta modificar o valor de uma variável declarada com const. Em Zig, const declara um valor imutável — uma vez atribuído, ele não pode ser alterado. Essa é uma decisão de design intencional: Zig favorece a imutabilidade por padrão, e você precisa usar var explicitamente quando precisa de mutabilidade.
Causas Comuns
1. Tentar Reatribuir uma Constante
pub fn main() void {
const x = 10;
x = 20; // ERRO: cannot assign to constant
}
2. Tentar Modificar Parâmetro de Função
Em Zig, parâmetros de função são sempre imutáveis:
fn incrementar(valor: u32) u32 {
valor += 1; // ERRO: cannot assign to constant
return valor;
}
3. Tentar Modificar Captura de for/while
pub fn main() void {
var arr = [_]u32{ 1, 2, 3, 4, 5 };
for (arr) |item| {
item = item * 2; // ERRO: cannot assign to constant
}
}
4. Tentar Modificar Captura de Optional
pub fn main() void {
var opcional: ?u32 = 42;
if (opcional) |valor| {
valor = 100; // ERRO: cannot assign to constant
}
_ = opcional;
}
5. Tentar Modificar Elemento Via Slice Const
fn processar(dados: []const u8) void {
dados[0] = 'X'; // ERRO: cannot assign — slice é const
}
6. Modificar Campo de Struct Const
const Ponto = struct {
x: f64,
y: f64,
};
pub fn main() void {
const p = Ponto{ .x = 1.0, .y = 2.0 };
p.x = 3.0; // ERRO: cannot assign to constant
}
Como Corrigir
Solução 1: Usar var ao Invés de const
Se a variável precisa ser modificada, declare-a com var:
pub fn main() void {
var x: u32 = 10;
x = 20; // OK: 'var' permite reatribuição
_ = x;
}
Solução 2: Criar Cópia Local em Funções
Parâmetros são sempre const, então crie uma cópia local:
fn incrementar(valor: u32) u32 {
var resultado = valor; // Cópia local mutável
resultado += 1;
return resultado;
}
Ou simplesmente:
fn incrementar(valor: u32) u32 {
return valor + 1; // Sem necessidade de variável mutável
}
Solução 3: Usar Ponteiro em Capturas de for
Para modificar elementos de um array durante iteração, use captura por ponteiro:
pub fn main() void {
var arr = [_]u32{ 1, 2, 3, 4, 5 };
for (&arr) |*item| {
item.* = item.* * 2; // OK: modifica via ponteiro
}
}
Solução 4: Usar Ponteiro em Capturas de Optional
pub fn main() void {
var opcional: ?u32 = 42;
if (opcional) |*valor| {
valor.* = 100; // OK: modifica via ponteiro
}
_ = opcional;
}
Solução 5: Aceitar Slice Mutável
fn processar(dados: []u8) void { // Sem 'const' no slice
dados[0] = 'X'; // OK: slice mutável
}
Solução 6: Declarar Struct como var
const Ponto = struct {
x: f64,
y: f64,
};
pub fn main() void {
var p = Ponto{ .x = 1.0, .y = 2.0 }; // 'var' permite modificar campos
p.x = 3.0; // OK
_ = p;
}
const vs var — Quando Usar Cada Um
Use const quando:
- O valor não precisa mudar após a inicialização
- Você está declarando constantes de configuração
- É um valor calculado uma vez e usado várias vezes
- Sempre que possível (é o padrão recomendado em Zig)
Use var quando:
- O valor precisa ser atualizado em um loop
- Você está construindo um resultado incrementalmente
- A variável é um acumulador ou contador
- O estado da variável muda ao longo da execução
const std = @import("std");
pub fn main() void {
// Use const para valores que não mudam
const limite = 100;
const nome = "Zig";
// Use var para valores que mudam
var soma: u32 = 0;
var i: u32 = 0;
while (i < limite) : (i += 1) {
soma += i;
}
std.debug.print("{s}: soma = {}\n", .{ nome, soma });
}
Filosofia do Zig: Imutabilidade por Padrão
O Zig favorece const por padrão por várias razões:
- Legibilidade: Ao ler código, você sabe que valores
constnão mudam - Otimização: O compilador pode otimizar melhor quando sabe que valores são imutáveis
- Segurança: Previne modificações acidentais
- Concorrência: Valores imutáveis são intrinsecamente thread-safe
O compilador Zig inclusive emitirá um aviso se você declarar algo como var mas nunca modificá-lo, sugerindo que use const.
Erros Relacionados
- unused local variable — Variável declarada mas não usada
- type mismatch in assignment — Tipo incompatível na atribuição
- expected type ‘X’, found ‘Y’ — Tipos incompatíveis