---
title: "Type Coercion Failed — Como Resolver em Zig"
url: "https://ziglang.com.br/erros/type-coercion-failed-como-resolver-em-zig/"
markdown_url: "https://ziglang.com.br/erros/type-coercion-failed-como-resolver-em-zig.MD"
description: "Entenda o erro 'type coercion failed' em Zig, que ocorre quando o compilador não consegue converter automaticamente entre tipos. Veja como resolver."
date: "2026-02-21"
author: "Zig Brasil"
---

# Type Coercion Failed — Como Resolver em Zig

Entenda o erro 'type coercion failed' em Zig, que ocorre quando o compilador não consegue converter automaticamente entre tipos. Veja como resolver.


# Type Coercion Failed — Como Resolver em Zig

## O Que Este Erro Significa

O erro `type coercion failed` ocorre em tempo de compilação quando Zig tenta converter automaticamente um valor de um tipo para outro e essa conversão não é permitida ou segura. Zig tem regras rígidas de coerção de tipos para prevenir bugs sutis — diferente de C, que faz conversões implícitas perigosas livremente.

Mensagens típicas do compilador:

```
error: expected type 'u32', found 'i32'
```

```
error: type 'u8' cannot represent all values of type 'u16'
```

Zig permite apenas coerções que são comprovadamente seguras. Para conversões que podem perder dados, o programador deve usar casts explícitos.

## Causas Comuns

### 1. Atribuir Tipo Signed a Unsigned (ou Vice-Versa)

```zig
pub fn main() void {
    const a: i32 = 42;
    const b: u32 = a; // ERRO: i32 pode ter valores negativos que u32 não representa
    _ = b;
}
```

### 2. Atribuir Tipo Maior a Tipo Menor

```zig
pub fn main() void {
    const a: u32 = 100;
    const b: u8 = a; // ERRO: u32 pode ter valores > 255
    _ = b;
}
```

### 3. Misturar Inteiro e Float

```zig
pub fn main() void {
    const a: f64 = 3.14;
    const b: u32 = a; // ERRO: f64 não coerce para u32
    _ = b;
}
```

### 4. Coerção de Ponteiro Incompatível

```zig
pub fn main() void {
    var x: u32 = 42;
    const ptr: *u32 = &x;
    const ptr2: *i32 = ptr; // ERRO: *u32 não coerce para *i32
    _ = ptr2;
}
```

### 5. Retorno de Tipo Incorreto

```zig
fn calcular() u32 {
    const resultado: i64 = 100;
    return resultado; // ERRO: i64 não coerce para u32
}
```

## Como Corrigir

### Solucao 1: Usar @intCast para Inteiros

```zig
pub fn main() void {
    const a: u32 = 100;
    const b: u8 = @intCast(a); // Conversão explícita — panic se a > 255
    _ = b;
}
```

### Solucao 2: Usar @intFromFloat e @floatFromInt

```zig
pub fn main() void {
    const f: f64 = 3.14;
    const i: u32 = @intFromFloat(f); // Converte float para int (trunca)
    _ = i; // i == 3

    const j: u32 = 42;
    const g: f64 = @floatFromInt(j); // Converte int para float
    _ = g; // g == 42.0
}
```

### Solucao 3: Usar @as para Coerção Explícita

```zig
pub fn main() void {
    // @as faz coerção quando ela é segura
    const a: u8 = 42;
    const b: u32 = @as(u32, a); // u8 -> u32 é sempre seguro (widening)
    _ = b;
}
```

### Solucao 4: Usar @bitCast para Reinterpretação

```zig
pub fn main() void {
    const a: i32 = -1;
    const b: u32 = @bitCast(a); // Mesmo padrão de bits, tipo diferente
    _ = b; // b == 4294967295
}
```

### Solucao 5: Usar std.math.cast para Conversão Segura

```zig
const std = @import("std");

pub fn main() void {
    const a: i32 = -5;
    const b: ?u32 = std.math.cast(u32, a);
    if (b) |valor| {
        std.debug.print("Conversão ok: {}\n", .{valor});
    } else {
        std.debug.print("Valor negativo, não pode converter\n", .{});
    }
}
```

### Solucao 6: Ajustar o Tipo da Variável

Muitas vezes a melhor solução é usar o tipo correto desde o início:

```zig
pub fn main() void {
    // Ao invés de converter, use o tipo certo
    const largura: u32 = 800;
    const metade: u32 = largura / 2; // Sem conversão necessária
    _ = metade;
}
```

## Coerções Permitidas Automaticamente

Zig permite certas coerções implícitas que são sempre seguras:

```zig
pub fn main() void {
    // Widening (tipo menor para maior) — sempre seguro
    const a: u8 = 42;
    const b: u16 = a;  // OK: u8 -> u16
    const c: u32 = b;  // OK: u16 -> u32
    const d: u64 = c;  // OK: u32 -> u64

    // Ponteiro para slice — seguro
    var arr = [_]u8{ 1, 2, 3 };
    const slice: []u8 = &arr;  // OK

    // *[N]T para []T
    const slice2: []const u8 = &arr;  // OK
    _ = d;
    _ = slice;
    _ = slice2;
}
```

## Coerções Proibidas (Requerem Cast Explícito)

| De | Para | Solução |
|----|------|---------|
| `i32` | `u32` | `@intCast` ou `@bitCast` |
| `u32` | `u8` | `@intCast` (panic se > 255) |
| `f64` | `u32` | `@intFromFloat` |
| `u32` | `f64` | `@floatFromInt` |
| `*u32` | `*i32` | `@ptrCast` |
| `usize` | `u32` | `@intCast` |

## Comptime vs Runtime

Em comptime, Zig pode avaliar se a conversão é segura:

```zig
pub fn main() void {
    // Em comptime, o compilador verifica o valor real
    const a: comptime_int = 42;
    const b: u8 = a; // OK: 42 cabe em u8
    _ = b;

    const c: comptime_int = 300;
    // const d: u8 = c; // ERRO: 300 não cabe em u8
    _ = c;
}
```

## Erros Relacionados

- [Signed/unsigned mismatch](/erros/erro-signed-unsigned/) — Mistura de signed/unsigned
- [Integer truncation](/erros/erro-truncation/) — Truncamento de inteiro
- [Type mismatch assignment](/erros/erro-type-mismatch-assignment/) — Tipo incompatível em atribuição
- [Pointer cast alignment](/erros/erro-pointer-cast-alignment/) — Alinhamento de cast de ponteiro

## Links Úteis

- [Documentação oficial do Zig — Type Coercion](https://ziglang.org/documentation/master/#Type-Coercion)
- [Builtins de conversão: @intCast, @floatFromInt](/builtins/)
- [Tutorial sobre tipos em Zig](/tutoriais/)
