---
title: "@as em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@as-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@as-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @as em Zig. Aprenda a fazer conversão explícita de tipos (type cast) com exemplos práticos em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# @as em Zig — Referência e Exemplos

Referência completa do @as em Zig. Aprenda a fazer conversão explícita de tipos (type cast) com exemplos práticos em português.


# @as em Zig

O `@as` é o builtin de conversão explícita de tipos (type cast) do Zig. Ele permite converter um valor de um tipo para outro de forma segura e explícita, garantindo que a conversão é válida. Ao contrário de casts inseguros em C, o `@as` só permite conversões que o compilador pode verificar como seguras ou que resultam em coerção implícita documentada.

## Sintaxe

```zig
@as(comptime T: type, valor: anytype) T
```

## O que faz

O `@as` realiza uma conversão de tipo explícita (type coercion), convertendo o valor fornecido para o tipo de destino especificado. O Zig possui um sistema sofisticado de coerção implícita, e o `@as` é a forma de invocar esse sistema explicitamente.

Essa conversão é usada quando o compilador não consegue inferir o tipo desejado automaticamente, ou quando o programador deseja tornar a intenção clara no código.

## Parâmetros

- **T** (`type`, comptime): O tipo de destino para a conversão. Deve ser conhecido em tempo de compilação.
- **valor** (`anytype`): O valor a ser convertido. Deve ser compatível com o tipo de destino segundo as regras de coerção do Zig.

## Valor de retorno

Retorna o valor convertido para o tipo `T`.

## Exemplos práticos

### Exemplo 1: Removendo ambiguidade de tipos literais

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

test "tipo literal com @as" {
    // Literais inteiros são comptime_int — @as define o tipo concreto
    const x = @as(u32, 42);
    try std.testing.expect(@TypeOf(x) == u32);

    // Sem @as, o compilador pode não saber qual tipo usar
    const y = @as(i64, -100);
    try std.testing.expect(@TypeOf(y) == i64);

    // Literais float são comptime_float
    const pi = @as(f32, 3.14159);
    try std.testing.expect(@TypeOf(pi) == f32);
}
```

### Exemplo 2: Conversão em chamadas de função

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

fn processarBytes(dados: []const u8) usize {
    return dados.len;
}

fn somarF64(a: f64, b: f64) f64 {
    return a + b;
}

test "conversão para argumentos de função" {
    // Converter inteiros para o tipo esperado pela função
    const resultado = somarF64(@as(f64, 10), @as(f64, 20));
    try std.testing.expect(resultado == 30.0);

    // Converter string literal para slice
    const tamanho = processarBytes(@as([]const u8, "hello"));
    try std.testing.expect(tamanho == 5);
}
```

### Exemplo 3: Uso com optionals e error unions

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

fn buscar(id: u32) ?[]const u8 {
    if (id == 1) return "encontrado";
    return null;
}

test "conversão com optionals" {
    // Converter null para um tipo optional específico
    const valor: ?u32 = @as(?u32, null);
    try std.testing.expect(valor == null);

    // Converter um valor para optional
    const numero: ?u32 = @as(?u32, 42);
    try std.testing.expect(numero.? == 42);

    // Converter para error union
    const resultado: anyerror!u32 = @as(anyerror!u32, 100);
    try std.testing.expect((try resultado) == 100);
}
```

## Casos de uso comuns

1. **Desambiguação de literais**: Quando um literal numérico pode ser interpretado como vários tipos, `@as` define o tipo exato.

2. **Parâmetros de formatação**: Em `std.debug.print` e funções similares, `@as` garante que os valores no tuple `.{}` tenham o tipo correto.

3. **Conversão segura entre tipos numéricos**: Converter entre tamanhos de inteiros ou entre inteiro e float quando a conversão é segura.

4. **Inicialização de optionals e error unions**: Converter `null` ou valores para tipos optional/error union específicos.

5. **Interoperabilidade**: Converter tipos ao chamar funções C importadas que esperam tipos específicos.

```zig
const c = @cImport(@cInclude("stdlib.h"));

fn alocar(tamanho: usize) ?[*]u8 {
    return @as(?[*]u8, @ptrCast(c.malloc(tamanho)));
}
```

## Diferença entre @as e outros casts

O `@as` realiza apenas coerções seguras que o Zig já permitiria implicitamente. Para conversões que alteram a representação ou a interpretação dos dados, existem builtins específicos:

- `@intFromFloat` / `@floatFromInt` — Conversão entre inteiro e float
- `@ptrCast` — Conversão entre tipos de ponteiro
- `@intFromPtr` / `@ptrFromInt` — Conversão entre ponteiro e inteiro
- `@truncate` — Truncar inteiros para tamanhos menores

## Perguntas Frequentes

**Quando usar `@as` vs conversão implícita?**

O Zig permite coerção implícita em muitos casos — por exemplo, um `u8` é automaticamente promovido para `u32` quando necessário. Use `@as` quando o compilador não consegue inferir o tipo, quando você quer tornar a intenção explícita no código, ou quando está trabalhando com literais comptime que poderiam ser ambíguos.

**`@as` pode causar perda de dados?**

Não. `@as` só permite coerções que o Zig considera seguras — por exemplo, de um tipo menor para um maior (`u8` → `u32`), ou de `comptime_int` para um tipo concreto. Para conversões que podem perder dados (como `u32` → `u8`), use `@truncate` ou `@intCast`. O compilador emitirá um erro se você tentar usar `@as` para uma conversão não permitida.

**Por que o erro "expected type X, found Y" some com @as?**

Literais como `42` têm tipo `comptime_int` e literais como `3.14` têm tipo `comptime_float`. Esses tipos se adaptam ao contexto, mas às vezes o compilador não tem contexto suficiente. `@as(u32, 42)` força o tipo explicitamente, resolvendo a ambiguidade.

## Coerções permitidas pelo @as

O `@as` segue as mesmas regras de coerção implícita do Zig. As principais são:

| De | Para | Observação |
|----|------|-----------|
| `comptime_int` | qualquer inteiro | sem perda se valor cabe |
| `comptime_float` | qualquer float | sem perda |
| inteiro menor | inteiro maior (mesmo sinal) | zero-extend ou sign-extend |
| `T` | `?T` | wrap em optional |
| `T` | `E!T` | wrap em error union |
| `*[N]T` | `[]T` | coerção de array para slice |
| `[*:0]T` | `[*]T` | remover sentinela |

Qualquer conversão fora dessas regras exige builtins específicos como `@intCast`, `@floatCast`, `@ptrCast`, etc.

## Builtins relacionados

- [@intFromFloat](/builtins/int-from-float/) — Converte float para inteiro
- [@floatFromInt](/builtins/float-from-int/) — Converte inteiro para float
- [@ptrCast](/builtins/ptr-cast/) — Conversão entre tipos de ponteiro
- [@intFromPtr](/builtins/int-from-ptr/) — Converte ponteiro para inteiro
- [@TypeOf](/builtins/type-of/) — Obtém o tipo de uma expressão

## Tutoriais relacionados

- [Sistema de tipos do Zig](/tutoriais/tipos/)
- [Conversões de tipo em Zig](/tutoriais/conversoes/)
- [Interoperabilidade com C](/tutoriais/interop-c/)
