expected type 'X', found 'Y' — Como Resolver em Zig

expected type ‘X’, found ‘Y’ — Como Resolver em Zig

O Que Este Erro Significa

O erro expected type 'X', found 'Y' é uma das mensagens de erro mais comuns do compilador Zig. Ele aparece quando você tenta usar um valor de um tipo onde o compilador espera outro tipo diferente. Zig é uma linguagem com tipagem estática e rigorosa — isso significa que o compilador verifica todos os tipos em tempo de compilação e não permite conversões implícitas que possam causar perda de dados ou comportamento inesperado.

Diferente de linguagens como C, onde conversões implícitas entre tipos numéricos são permitidas livremente, Zig exige que o programador seja explícito sobre conversões de tipo. Isso pode parecer restritivo no início, mas previne uma classe inteira de bugs sutis.

Causas Comuns

1. Atribuir um Tipo Numérico Diferente

Uma das causas mais frequentes é misturar tipos inteiros de tamanhos diferentes.

const std = @import("std");

pub fn main() void {
    const x: u32 = 42;
    const y: u64 = x; // ERRO: expected type 'u64', found 'u32'
    _ = y;
}

Embora um u32 caiba dentro de um u64, Zig não faz essa conversão automaticamente. Você precisa ser explícito.

2. Passar Argumento com Tipo Errado para Função

fn soma(a: i32, b: i32) i32 {
    return a + b;
}

pub fn main() void {
    const x: i64 = 10;
    const y: i64 = 20;
    const resultado = soma(x, y); // ERRO: expected type 'i32', found 'i64'
    _ = resultado;
}

3. Retornar Tipo Diferente do Declarado

fn obterValor() u32 {
    const valor: u64 = 100;
    return valor; // ERRO: expected type 'u32', found 'u64'
}

4. Misturar Tipos de Ponteiro

fn processar(dados: []const u8) void {
    _ = dados;
}

pub fn main() void {
    var buffer: [10]u8 = undefined;
    processar(&buffer); // ERRO: expected type '[]const u8', found '*[10]u8'
}

5. Confundir Optional com Tipo Base

fn obterNome() ?[]const u8 {
    return "Zig";
}

pub fn main() void {
    const nome: []const u8 = obterNome(); // ERRO: expected type '[]const u8', found '?[]const u8'
    _ = nome;
}

Como Corrigir

Solução 1: Usar @intCast para Conversões Numéricas

Quando você sabe que a conversão é segura, use @intCast:

const x: u32 = 42;
const y: u64 = @intCast(x); // Conversão explícita de u32 para u64

Para a direção oposta (tipo maior para menor), @intCast verificará em tempo de execução (em modo Debug) se o valor cabe:

const grande: u64 = 100;
const pequeno: u32 = @intCast(grande); // OK se o valor cabe em u32

Solução 2: Usar @as para Coerção Explícita

O @as é útil quando o compilador precisa de uma dica de tipo:

const x = @as(u64, 42); // Tipo explícito para literal

Solução 3: Ajustar Tipos de Ponteiro e Slice

Para converter arrays em slices, use o operador de slicing:

fn processar(dados: []const u8) void {
    _ = dados;
}

pub fn main() void {
    var buffer: [10]u8 = undefined;
    processar(buffer[0..]); // Converte array em slice
}

Solução 4: Desempacotar Optional Antes de Usar

fn obterNome() ?[]const u8 {
    return "Zig";
}

pub fn main() void {
    const nome: []const u8 = obterNome() orelse "desconhecido";
    _ = nome;
}

Ou use if para verificar:

if (obterNome()) |nome| {
    // usar nome aqui — tipo é []const u8
    _ = nome;
}

Solução 5: Usar @floatFromInt e @intFromFloat

Para conversões entre inteiros e ponto flutuante:

const inteiro: i32 = 42;
const decimal: f64 = @floatFromInt(inteiro); // i32 -> f64

const pi: f64 = 3.14;
const truncado: i32 = @intFromFloat(pi); // f64 -> i32 (trunca para 3)

Dicas Importantes

  1. Literais numéricos são especiais — Zig trata literais como comptime_int, que podem ser convertidos automaticamente para qualquer tipo inteiro, desde que o valor caiba. O erro só aparece com variáveis tipadas.

  2. Leia o erro completo — O compilador muitas vezes mostra notas adicionais sugerindo a conversão correta.

  3. Use @TypeOf — Para descobrir o tipo de uma expressão durante debug: @compileLog(@TypeOf(variavel)).

  4. Prefira aceitar tipos genéricos — Se sua função pode trabalhar com diferentes tamanhos de inteiro, considere usar anytype ou generics.

Erros Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.