@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
@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
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
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
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
Desambiguação de literais: Quando um literal numérico pode ser interpretado como vários tipos,
@asdefine o tipo exato.Parâmetros de formatação: Em
std.debug.printe funções similares,@asgarante que os valores no tuple.{}tenham o tipo correto.Conversão segura entre tipos numéricos: Converter entre tamanhos de inteiros ou entre inteiro e float quando a conversão é segura.
Inicialização de optionals e error unions: Converter
nullou valores para tipos optional/error union específicos.Interoperabilidade: Converter tipos ao chamar funções C importadas que esperam tipos específicos.
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
Builtins relacionados
- @intFromFloat — Converte float para inteiro
- @floatFromInt — Converte inteiro para float
- @ptrCast — Conversão entre tipos de ponteiro
- @intFromPtr — Converte ponteiro para inteiro
- @TypeOf — Obtém o tipo de uma expressão