comptime_int em Zig — O que é e Como Usar
Definição
comptime_int é o tipo inteiro de precisão arbitrária que existe apenas em tempo de compilação. Quando você escreve um literal inteiro como 42 ou 1_000_000 em Zig, ele é inicialmente do tipo comptime_int. Esse tipo não tem limite de tamanho — pode representar qualquer valor inteiro, por maior que seja — e nunca sofre overflow.
O comptime_int existe apenas durante a compilação. Antes de o código ser executado, ele deve ser convertido (explícita ou implicitamente) para um tipo concreto como u32, i64 ou usize.
Por que comptime_int Importa
- Sem overflow em comptime: Cálculos em tempo de compilação nunca perdem precisão.
- Literais flexíveis: Um literal como
42pode ser atribuído a qualquer tipo inteiro que o comporte, sem cast explícito. - Metaprogramação: Permite operações matemáticas complexas durante a compilação sem preocupação com limites de bits.
- Segurança: O compilador verifica se o valor cabe no tipo de destino antes de gerar código.
Exemplo Prático
Literais Inteiros e Coerção Automática
const std = @import("std");
pub fn main() void {
// 42 é comptime_int, convertido implicitamente para cada tipo
const a: u8 = 42;
const b: u32 = 42;
const c: i64 = 42;
const d: usize = 42;
std.debug.print("u8={}, u32={}, i64={}, usize={}\n", .{ a, b, c, d });
}
Cálculos de Precisão Arbitrária em Comptime
const std = @import("std");
const fatorial_20 = blk: {
var resultado: comptime_int = 1;
for (1..21) |i| {
resultado *= i;
}
break :blk resultado;
};
pub fn main() void {
// fatorial_20 = 2432902008176640000
// Cabe em u64, então a conversão é segura
const valor: u64 = fatorial_20;
std.debug.print("20! = {}\n", .{valor});
}
Erro de Compilação: Valor Não Cabe no Tipo
const std = @import("std");
pub fn main() void {
// ERRO de compilação: 256 não cabe em u8 (máximo é 255)
// const x: u8 = 256;
// OK: 255 cabe em u8
const x: u8 = 255;
std.debug.print("{}\n", .{x});
}
comptime_int vs Tipos Concretos
| Característica | comptime_int | u32, i64, etc. |
|---|---|---|
| Precisão | Arbitrária (ilimitada) | Fixa (N bits) |
| Overflow | Impossível | Detectado em safe mode |
| Existe em runtime | Nunca | Sim |
| Uso direto em structs | Apenas em comptime | Sim |
| Operações de I/O | Não | Sim |
Uso em Funções Genéricas
comptime_int é especialmente útil em funções genéricas que recebem parâmetros numéricos comptime. O compilador usa a precisão arbitrária para validar a escolha de tipo antes de gerar código:
const std = @import("std");
fn arrayDeTamanho(comptime n: comptime_int) [n]u8 {
// n é avaliado em comptime — pode ser usado como tamanho de array
var resultado: [n]u8 = undefined;
for (0..n) |i| {
resultado[i] = @intCast(i % 256);
}
return resultado;
}
pub fn main() void {
const arr = arrayDeTamanho(8);
std.debug.print("Array: {any}\n", .{arr});
}
Perguntas Frequentes
Por que Zig usa comptime_int em vez de inferir direto para i32?
Porque um literal como 1_000_000_000_000 não caberia em i32, mas cabe em i64. Ao manter o tipo como comptime_int até o ponto de uso, o compilador pode escolher o tipo concreto correto sem perda de precisão.
comptime_int e comptime_float são a mesma coisa?
Não. comptime_int é para literais inteiros (sem ponto decimal); comptime_float é para literais com ponto decimal como 3.14. O comptime_float usa 128 bits de precisão internamente.
Posso somar um comptime_int com um u32?
Sim, mas o resultado é u32. O valor comptime é convertido implicitamente, e o compilador verifica se o valor cabe no tipo antes da conversão.
Armadilhas Comuns
- Não pode existir em runtime: Uma variável
var x: comptime_int = 42;só é válida em contexto comptime. Em funções normais, o tipo deve ser concreto. - Divisão em comptime: Divisão de
comptime_inté exata. Dividir 7 por 2 resulta em erro se o resultado não for inteiro — use@divFloorou@divTruncpara controlar o comportamento. - Confundir com bigint:
comptime_intnão é um tipo de runtime como BigInteger em Java. Ele desaparece após a compilação.
Termos Relacionados
- comptime_float — Tipo float de alta precisão em comptime
- Comptime — Execução em tempo de compilação
- Type Coercion — Regras de conversão automática de tipos
- usize — Tipo inteiro nativo para índices