expected block expression — Como Resolver em Zig
O Que Este Erro Significa
O erro expected block expression ocorre quando o compilador Zig espera encontrar um bloco de código delimitado por chaves { }, mas encontra outra coisa. Blocos são fundamentais na sintaxe do Zig — são usados para corpos de funções, branches de if/else, corpos de while/for, e como expressões que produzem valores.
Causas Comuns
1. Corpo de Função Sem Chaves
fn dobrar(x: u32) u32
return x * 2; // ERRO: expected block expression (faltam { })
2. If Sem Chaves (Zig Não Aceita)
Diferente de C, Zig exige chaves para blocos de controle:
pub fn main() void {
const x: u32 = 5;
if (x > 3)
x = 10; // ERRO: expected block expression
}
3. While Sem Chaves
pub fn main() void {
var i: u32 = 0;
while (i < 10)
i += 1; // ERRO: expected block expression
}
4. For Sem Chaves
pub fn main() void {
const arr = [_]u32{ 1, 2, 3 };
for (arr) |item|
_ = item; // ERRO: expected block expression
}
5. Else Sem Chaves
pub fn main() void {
const x: u32 = 5;
if (x > 3) {
// ...
} else
return; // ERRO: expected block expression após else
}
6. Confundir Sintaxe de Expressão com Statement
pub fn main() void {
// Em Zig, if como statement precisa de bloco
const x: u32 = 5;
if (x > 3) return; // ERRO em alguns contextos
}
Note: Zig permite if (cond) return; em certos contextos, mas não para statements genéricos sem chaves.
Como Corrigir
Solução 1: Adicionar Chaves ao Corpo da Função
fn dobrar(x: u32) u32 {
return x * 2; // Correto: corpo entre { }
}
Solução 2: Sempre Usar Chaves com if
pub fn main() void {
var x: u32 = 5;
if (x > 3) {
x = 10; // Correto: bloco com chaves
}
_ = x;
}
Solução 3: Sempre Usar Chaves com while
pub fn main() void {
var i: u32 = 0;
while (i < 10) {
i += 1; // Correto: bloco com chaves
}
}
Para while com expressão de continuação:
pub fn main() void {
var i: u32 = 0;
while (i < 10) : (i += 1) {
// corpo do loop
}
}
Solução 4: Sempre Usar Chaves com for
pub fn main() void {
const arr = [_]u32{ 1, 2, 3 };
for (arr) |item| {
_ = item; // Correto: bloco com chaves
}
}
Solução 5: Chaves no else
pub fn main() void {
const x: u32 = 5;
if (x > 3) {
// ...
} else {
return; // Correto: else com bloco
}
}
Blocos como Expressões em Zig
Em Zig, blocos podem ser usados como expressões que produzem um valor usando labels:
pub fn main() void {
const x = blk: {
const a: u32 = 10;
const b: u32 = 20;
break :blk a + b; // O bloco "retorna" 30
};
_ = x; // x == 30
}
Isso é útil para cálculos complexos que precisam de variáveis temporárias.
Diferença entre Zig e C/C++
Em C/C++, blocos de uma linha sem chaves são permitidos:
// C/C++ — válido
if (x > 3)
x = 10;
Em Zig, isso é sempre um erro. A decisão de exigir chaves foi intencional para evitar bugs como o famoso “goto fail” da Apple, onde indentação enganosa escondia um bug crítico de segurança.
// Zig — sempre use chaves
if (x > 3) {
x = 10;
}
Padrões Comuns
Blocos de Uma Linha
Mesmo para blocos curtos, use chaves. A formatação em uma linha é aceitável:
if (x > 3) { return; }
Mas zig fmt normalmente expande para:
if (x > 3) {
return;
}
Switch com Blocos
Cada braço do switch pode ter um bloco se precisar de múltiplas expressões:
fn processar(op: u8) u32 {
return switch (op) {
'+' => blk: {
// lógica complexa
break :blk 1;
},
'-' => 2,
else => 0,
};
}
Erros Relacionados
- expected expression — Expressão esperada pelo compilador
- expected ‘}’ — Chave de fechamento faltando
- expected ‘;’ — Ponto e vírgula faltando