Type Mismatch in Assignment — Como Resolver em Zig

Type Mismatch in Assignment — Como Resolver em Zig

O Que Este Erro Significa

O erro de incompatibilidade de tipo em atribuição ocorre quando você tenta atribuir um valor a uma variável cujo tipo não é compatível com o valor fornecido. Zig é extremamente rigoroso com tipos — não há conversões implícitas entre a maioria dos tipos, mesmo quando a conversão seria “segura” em outras linguagens.

A mensagem de erro geralmente aparece como:

error: expected type 'X', found 'Y'
note: cannot implicitly convert ...

Causas Comuns

1. Atribuir Tipo Inteiro Diferente

pub fn main() void {
    var x: u16 = 100;
    const y: u32 = 200;
    x = y; // ERRO: expected type 'u16', found 'u32'
}

2. Atribuir Float para Inteiro ou Vice-Versa

pub fn main() void {
    var x: i32 = 0;
    const pi: f64 = 3.14;
    x = pi; // ERRO: expected type 'i32', found 'f64'
}

3. Atribuir Optional para Tipo Base

pub fn main() void {
    var nome: []const u8 = "padrão";
    const talvez_nome: ?[]const u8 = "Zig";
    nome = talvez_nome; // ERRO: expected '[]const u8', found '?[]const u8'
}

4. Atribuir Error Union para Tipo Base

fn ler() !u32 {
    return 42;
}

pub fn main() void {
    var valor: u32 = 0;
    valor = ler(); // ERRO: expected 'u32', found '!u32' (error union)
}

5. Atribuir Ponteiro de Tipo Diferente

pub fn main() void {
    var buffer: [10]u8 = undefined;
    var ptr: [*]u32 = &buffer; // ERRO: tipos de ponteiro incompatíveis
    _ = ptr;
}

6. Atribuir Resultado de Função com Tipo Diferente

fn obterTexto() []const u8 {
    return "olá";
}

pub fn main() void {
    var numero: u32 = 0;
    numero = obterTexto(); // ERRO: expected 'u32', found '[]const u8'
    _ = numero;
}

Como Corrigir

Solução 1: Converter Explicitamente Entre Inteiros

Use @intCast para conversões entre tipos inteiros:

pub fn main() void {
    var x: u16 = 100;
    const y: u32 = 200;
    x = @intCast(y); // Conversão explícita — verificada em Debug
}

Solução 2: Converter Entre Float e Inteiro

pub fn main() void {
    var x: i32 = 0;
    const pi: f64 = 3.14;
    x = @intFromFloat(pi); // Converte float para inteiro (trunca)
}

Para a conversão inversa:

pub fn main() void {
    var y: f64 = 0.0;
    const n: i32 = 42;
    y = @floatFromInt(n); // Converte inteiro para float
}

Solução 3: Desempacotar Optional com orelse

pub fn main() void {
    var nome: []const u8 = "padrão";
    const talvez_nome: ?[]const u8 = "Zig";
    nome = talvez_nome orelse "desconhecido"; // Desempacota optional
}

Solução 4: Tratar Error Union com try ou catch

fn ler() !u32 {
    return 42;
}

pub fn main() !void {
    var valor: u32 = 0;
    valor = try ler(); // 'try' desempacota o error union
}

Ou com catch:

pub fn main() void {
    var valor: u32 = 0;
    valor = ler() catch 0; // Valor padrão se houver erro
}

Solução 5: Usar o Tipo Correto na Declaração

Às vezes a melhor solução é declarar a variável com o tipo certo:

pub fn main() void {
    var x: u32 = 100; // Usar u32 ao invés de u16
    const y: u32 = 200;
    x = y; // OK: mesmos tipos
}

Solução 6: Usar @as Para Coerção Explícita

pub fn main() void {
    var x: u64 = 0;
    x = @as(u64, 42); // Explicitamente diz que 42 é u64
}

Entendendo as Regras de Coerção do Zig

Zig permite algumas coerções automáticas em situações específicas:

  1. Ponteiro para slice: *[N]T pode ser convertido para []T
  2. Enum para int: Se o enum tem representação inteira
  3. Widening de inteiros em comptime: Literais comptime podem ser atribuídos a qualquer tipo que os comporte

Mas não permite:

  • u32 para u16 (pode perder dados)
  • i32 para u32 (pode ser negativo)
  • f64 para i32 (perda de informação)
  • ?T para T (pode ser null)
  • !T para T (pode ser erro)

Padrão: Verificar Tipo com @TypeOf

Quando não tem certeza do tipo de uma expressão:

pub fn main() void {
    const x = alguma_funcao();
    @compileLog(@TypeOf(x)); // Imprime o tipo durante compilação
}

Erros Relacionados

Continue aprendendo Zig

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