Error Payload Not Used — Como Resolver em Zig
O Que Este Erro Significa
O erro de compilação error payload capture is not used ocorre quando você captura o payload (valor) de um catch ou else em uma variável, mas nunca usa essa variável no corpo do bloco. Zig não permite variáveis não utilizadas — isso é tratado como um possível bug no código.
A mensagem do compilador:
error: unused capture
Ou:
error: error payload capture 'err' is not used
Esse comportamento é consistente com a filosofia de Zig de não tolerar código “morto” que pode indicar um bug lógico.
Causas Comuns
1. Capturar Erro em catch sem Usar
const std = @import("std");
pub fn main() void {
const file = std.fs.cwd().openFile("dados.txt", .{}) catch |err| {
// ERRO DE COMPILAÇÃO: err não é usado
std.debug.print("Falha ao abrir arquivo\n", .{});
return;
};
defer file.close();
}
2. Capturar Valor em if/else sem Usar
const std = @import("std");
fn obterDados() ![]const u8 {
return error.Falha;
}
pub fn main() void {
if (obterDados()) |dados| {
// ERRO: dados não é usado
std.debug.print("Sucesso\n", .{});
} else |err| {
// ERRO: err não é usado
std.debug.print("Erro ocorreu\n", .{});
}
}
3. Capturar Payload de Optional sem Usar
const std = @import("std");
pub fn main() void {
const valor: ?u32 = 42;
if (valor) |v| {
// ERRO: v não é usado
std.debug.print("Tem valor\n", .{});
}
}
4. Capturar Erro para Log que Foi Removido
const std = @import("std");
fn processar() !void {
return error.Falha;
}
pub fn main() void {
processar() catch |err| {
// Linha de log comentada, err ficou sem uso
// std.debug.print("Erro: {}\n", .{err});
return;
};
}
Como Corrigir
Solucao 1: Usar o Payload Capturado
A solução mais óbvia — use a variável capturada:
const std = @import("std");
pub fn main() void {
const file = std.fs.cwd().openFile("dados.txt", .{}) catch |err| {
std.debug.print("Falha ao abrir arquivo: {}\n", .{err}); // Usa err
return;
};
defer file.close();
}
Solucao 2: Usar Underscore para Descartar
Se você realmente não precisa do payload, use _:
const std = @import("std");
pub fn main() void {
const file = std.fs.cwd().openFile("dados.txt", .{}) catch |_| {
std.debug.print("Falha ao abrir arquivo\n", .{});
return;
};
defer file.close();
}
Solucao 3: Omitir a Captura Quando Possível
Em alguns casos, você pode omitir a captura totalmente:
const std = @import("std");
pub fn main() void {
// Sem captura — catch com bloco simples
const file = std.fs.cwd().openFile("dados.txt", .{}) catch {
std.debug.print("Falha ao abrir arquivo\n", .{});
return;
};
defer file.close();
}
Solucao 4: Usar _ para Optional Payload
const std = @import("std");
pub fn main() void {
const valor: ?u32 = 42;
if (valor) |_| {
std.debug.print("Tem valor\n", .{});
}
// Ou, se só quer testar existência:
if (valor != null) {
std.debug.print("Tem valor\n", .{});
}
}
Solucao 5: Tratar Erros Específicos com switch
const std = @import("std");
pub fn main() void {
const file = std.fs.cwd().openFile("dados.txt", .{}) catch |err| switch (err) {
error.FileNotFound => {
std.debug.print("Arquivo não encontrado\n", .{});
return;
},
error.AccessDenied => {
std.debug.print("Sem permissão\n", .{});
return;
},
else => {
std.debug.print("Erro: {}\n", .{err}); // err é usado aqui
return;
},
};
defer file.close();
}
Solucao 6: Simplificar com catch e Valor
const std = @import("std");
fn dividir(a: u32, b: u32) !u32 {
if (b == 0) return error.DivisaoPorZero;
return a / b;
}
pub fn main() void {
// Se não precisa do erro, use catch com valor direto
const resultado = dividir(10, 0) catch 0;
std.debug.print("resultado: {}\n", .{resultado});
}
Formas Idiomáticas em Zig
catch sem Captura
// Quando o tipo do erro não importa
funcao() catch {
// Trata qualquer erro
return;
};
catch com Captura Usada
// Quando precisa logar ou tratar por tipo
funcao() catch |err| {
log.err("Falha: {}", .{err}); // err é usado
return;
};
catch com Descarte Explícito
// Quando captura é obrigatória mas valor não é necessário
funcao() catch |_| {
// _ descarta explicitamente o erro
return;
};
Por Que Zig Exige Isso
Zig trata variáveis não utilizadas como erros de compilação, não avisos, por uma razão: código não usado frequentemente indica bugs. Se você captura um erro mas não o examina, pode estar perdendo informação importante para depuração. A política de Zig é:
- Se precisa do valor, use-o.
- Se não precisa, declare explicitamente com
_. - Se nenhuma captura é necessária, omita-a.
Isso torna o código mais explícito e reduz bugs silenciosos.
Erros Relacionados
- Unused variable — Variável local não utilizada
- Error not handled — Erro não tratado
- Unreachable code — Código inalcançável