Menu

Tipos primitivos do Zero: inteiros, floats, Bool, String e Void

Os tipos embutidos que Zero te dá de saída: inteiros com e sem sinal de todas as larguras, floats, booleanos, caracteres, strings e o tipo vazio Void.

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íliaTiposNotas
Inteiros com sinali8, i16, i32, i64Complemento de dois.
Inteiros sem sinalu8, u16, u32, u64Apenas 0 e positivos.
Tamanho de ponteirousize, isizeLargura combina com o ponteiro da plataforma.
Floatsf32, f64IEEE-754.
Booleanobooltrue ou false.
CaracterecharUm único valor escalar Unicode.
StringStringString UTF-8.
VazioVoid"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:

  • i32 para a maioria da matemática com sinal. Largo o bastante para quase tudo o que você contaria, rápido em toda plataforma.
  • u8 para trabalho em nível de byte. Bytes de um arquivo, bytes em um buffer, bytes pela rede.
  • u32 / u64 para contagens não negativas quando a faixa importa. Offsets de arquivo acima de 2 GB, contagens grandes.
  • usize para tamanhos e índices. Tamanho de ponteiro — combina com o que a plataforma usa para endereçamento.
  • i64 para 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

SufixoTipoExemplo
_i8 / _i16 / _i32 / _i64Inteiro com sinal127_i8
_u8 / _u16 / _u32 / _u64Inteiro sem sinal255_u8
_usize / _isizeTamanho de ponteiro0_usize
_f32 / _f64Float0.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.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR