Os tipos embutidos
Zero te dá um conjunto pequeno e regular de tipos primitivos. Nada exótico, nada surpreendente — só os que toda linguagem de sistemas precisa, nomeados de forma consistente.
| Família | Tipos | Notas |
|---|---|---|
| Inteiros com sinal | i8, i16, i32, i64 | Complemento de dois. |
| Inteiros sem sinal | u8, u16, u32, u64 | Apenas 0 e positivos. |
| Tamanho de ponteiro | usize, isize | Largura combina com o ponteiro da plataforma. |
| Floats | f32, f64 | IEEE-754. |
| Booleano | bool | true ou false. |
| Caractere | char | Um único valor escalar Unicode. |
| String | String | String UTF-8. |
| Vazio | Void | "Nenhum valor útil." |
Essa é a lista completa de primitivos que você vai tocar no dia a dia. Tipos compostos — shapes, enums, choices — são construídos a partir desses.
Inteiros
Os tipos inteiros seguem um padrão de nomes uniforme: i para com sinal, u para sem sinal, seguidos da largura em bits. Então i32 é um inteiro com sinal de 32 bits; u8 é um byte sem sinal; i64 é um inteiro com sinal de 64 bits.
let small_signed: i8 = -120
let byte: u8 = 250
let id: i32 = 1
let big: i64 = 9_000_000_000
let index: usize = 0
O padrão para um literal sem sufixo é i32, a menos que o contexto ao redor force algo diferente:
let answer = 42 // i32
Quando precisar de uma largura específica, coloque um sufixo no literal ou anote a ligação:
let byte = 250_u8 // literal tipado
let byte: u8 = 250 // ligação tipada
As duas formas produzem o mesmo valor. A forma com sufixo no literal é prática quando você está passando um literal direto para uma função ou montando um struct:
let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }
Quando escolher cada largura
Uma regra de bolso curta:
i32para a maioria da matemática com sinal. Largo o bastante para quase tudo o que você contaria, rápido em toda plataforma.u8para trabalho em nível de byte. Bytes de um arquivo, bytes em um buffer, bytes pela rede.u32/u64para contagens não negativas quando a faixa importa. Offsets de arquivo acima de 2 GB, contagens grandes.usizepara tamanhos e índices. Tamanho de ponteiro — combina com o que a plataforma usa para endereçamento.i64para tempo desde a época e similares. Grande o bastante para nanossegundos por centenas de anos.
Escolher o menor tipo que cabe é boa prática; escolher um tipo pequeno demais e ter overflow é um problema muito maior do que escolher um bit largo demais.
Booleanos
let ok = true
let done: bool = false
bool tem exatamente dois valores: true e false. São literais, não constantes que você importa de algum lugar. A condição em if ou while é um bool — não há truthiness implícito para inteiros nem strings.
if ok {
check world.out.write("yes\n")
} else {
check world.out.write("no\n")
}
If/else cobre condicionais em detalhe.
Floats
f32 e f64 são números de ponto flutuante IEEE-754 de 32 e 64 bits, respectivamente. Use quando precisar de valores fracionários — medidas, razões, geometria. Para aritmética exata com moeda, prefira inteiros na menor unidade (centavos, satoshis) em vez de floats.
let ratio: f32 = 0.5
let pi: f64 = 3.141592653589793
f64 é o padrão para literais de float sem sufixo.
Caracteres e strings
Um char guarda um único valor escalar Unicode:
let initial: char = 'Z'
Um String é uma sequência de caracteres, tipicamente codificada como UTF-8 pela biblioteca padrão. Literais de string usam aspas duplas:
let message: String = "hello from zero\n"
Sequências de escape que você esperaria funcionam — \n para nova linha, \t para tab, \\ para uma contrabarra literal, \" para aspas duplas literais.
let multi_line = "line one\nline two\n"
A biblioteca padrão expõe visualizações em nível de byte sobre uma string para trabalho de baixo nível. A forma std.mem.span("zero") retorna um Span<u8> sobre os bytes — útil quando você está parseando, fazendo hash ou comparando byte a byte.
Void
Void é o tipo "sem valor útil de retorno" do Zero. Funções que existem para efeitos colaterais usam isso:
pub fun main(world: World) -> Void raises {
check world.out.write("hello\n")
}
main escreve algo e retorna. Não há valor para devolver, então o tipo é Void. Você vai ver Void na maioria das funções que tocam World — elas são escolhidas pelo efeito, não pelo resultado.
Underscores em literais numéricos
Literais numéricos longos podem usar underscores como separadores visuais. O compilador ignora, então eles servem só para legibilidade:
let big = 9_000_000_000_i64
let bytes = 1_048_576_u32 // 1 MiB
Use sempre que os dígitos estiverem difíceis de contar.
Cheat sheet de sufixos tipados em literais
| Sufixo | Tipo | Exemplo |
|---|---|---|
_i8 / _i16 / _i32 / _i64 | Inteiro com sinal | 127_i8 |
_u8 / _u16 / _u32 / _u64 | Inteiro sem sinal | 255_u8 |
_usize / _isize | Tamanho de ponteiro | 0_usize |
_f32 / _f64 | Float | 0.5_f32 |
Use quando estiver construindo um valor onde o contexto ao redor não fixa o tipo.
A seguir: funções
Primitivos não servem para nada sem algo para fazer com eles. A próxima documentação cobre funções em Zero — como declarar, retornar valores e juntar tudo para construir programas reais.
Perguntas frequentes
Quais tipos primitivos o Zero tem?
Zero vem com inteiros com sinal de tamanho fixo i8, i16, i32, i64; inteiros sem sinal u8, u16, u32, u64; inteiros do tamanho de ponteiro usize e isize; floats f32 e f64; bool; char; String; e Void para funções que não retornam nada útil.
Qual é o tipo inteiro padrão no Zero?
Um literal inteiro sem sufixo como 42 tem i32 por padrão, a menos que o contexto force outro tipo. Para usar uma largura específica, escreva o literal com um sufixo como 42_u8 ou 42_i64, ou anote o tipo da ligação explicitamente com let count: u8 = 42.
O Zero tem um tipo string separado?
Sim. Literais de string como "hello" têm um tipo string embutido que a biblioteca padrão trata como uma sequência de bytes (em geral UTF-8). Para trabalho em nível mais baixo com bytes, a biblioteca padrão expõe spans e utilitários de byte; para operações em nível de caractere existe char para valores escalares individuais.
O que Void significa em Zero?
Void é o tipo de retorno de uma função que não produz um valor útil — existe apenas para efeitos colaterais. A assinatura convencional pub fun main(world: World) -> Void raises usa Void porque main existe para fazer I/O e sair, não para produzir um valor.
Qual a diferença entre i32 e u32 em Zero?
i32 é um inteiro com sinal de 32 bits com faixa de −2.147.483.648 a 2.147.483.647. u32 é sem sinal e tem faixa de 0 a 4.294.967.295. Use tipos com sinal quando valores negativos são significativos; sem sinal quando valores negativos seriam um bug — para contagens, índices, tamanhos e por aí vai.