Uma forma de nomear um valor
Em Zero, você dá um nome a um valor com let:
let answer = 42
Essa é a sintaxe inteira. Não há var, não há const, não há auto. Uma única palavra-chave de ligação mantém a linguagem pequena — agentes e humanos aprendem uma vez e aplicam em todo lugar.
let introduz uma ligação local no escopo atual. Depois dessa linha, answer se refere a 42 até o fim do bloco que a contém.
Inferência de tipos
O compilador infere o tipo a partir do lado direito. O literal 42 tem tipo i32 por padrão, então answer é um i32. O literal "hello" é uma string, então:
let greeting = "hello"
vincula greeting a um valor string. Se você chama uma função que retorna um Pair<i32, u8>, a ligação tem tipo Pair<i32, u8>:
let pair = makePair(40, 2_u8)
Você não precisa escrever o tipo em toda ligação, o que mantém o código legível.
Anotações de tipo explícitas
Quando quiser documentar o tipo — ou forçar um específico quando a inferência escolheria algo diferente —, escreva o tipo depois de dois pontos:
let count: u8 = 10
let pair: Pair<i32, u8> = makePair(40, 2_u8)
Anotações também são uma dica ao compilador quando um literal pode ser um de vários tipos. O literal 10 poderia ser i32, i64, u8 e assim por diante; a anotação fixa o tipo.
Você também vai ver sufixos tipados em literais como alternativa a anotar a ligação:
let small = 10_u8 // u8 pelo sufixo do literal
let big = 10_i64 // i64 pelo sufixo do literal
As duas formas são válidas; escolha a que torna a intenção mais clara no ponto de chamada.
Ligações em ação
Um exemplo usando tanto a forma inferida quanto a explícita — clique em Run para tentar:
point é anotado explicitamente porque o lado direito é um struct literal. total é inferido — sum é declarada para retornar i32, então a ligação também é i32.
Escopo e shadowing
Uma ligação let é válida da linha que a declara até o fim do bloco que a contém. Blocos aninhados criam escopos novos:
pub fun main(world: World) -> Void raises {
let value = 1
if true {
let value = 2 // sombreia o 'value' externo dentro deste bloco
// aqui, value == 2
}
// de volta fora do if, value == 1 de novo
}
O value interno não muta o externo — é uma ligação separada que sai de escopo na chave de fechamento do bloco if. É o mesmo modelo de Rust e das linguagens da família ML. É especialmente comum quando você quer transformar um valor por uma série de passos sem inventar nomes novos para cada resultado intermediário.
O que let não faz
Algumas coisas que você pode esperar de outras linguagens e que let deliberadamente não inclui:
- Declarações só de tipo. Não há uma forma
let x: i32;que introduza uma ligação não inicializada. Uma ligação precisa ter um valor no ponto em que é declarada. - Destruturação por padrão (ainda). Algumas linguagens permitem
let (a, b) = pair. Zero é pequeno por desenho e atualmente foca em ligações por nome simples — confira a documentação atual para saber se destruturação chegou. - Múltiplas palavras-chave para vidas úteis diferentes. Sem
static,const,let mutou variantes separadas com escopo de bloco vs. escopo de função. Uma palavra-chave.
Se você vem do JavaScript, a analogia mais próxima é const — um nome ligado a um valor pelo resto do bloco, com shadowing em escopos internos. Se você vem do Rust, let aqui faz o mesmo papel do let do Rust sem a palavra-chave mut explícita.
Um padrão: construir um valor passo a passo
Ligações brilham quando você quer escrever uma computação como uma série de passos intermediários nomeados. Isso é bom tanto para humanos lendo quanto para agentes raciocinando localmente sobre cada linha:
Cada linha apresenta um novo fato para o resto da função usar. O compilador ainda produz código compacto — não há custo em tempo de execução por nomear os valores intermediários.
A seguir: tipos primitivos
let não significa muito sem algo para vincular. A próxima documentação percorre os tipos primitivos do Zero — as larguras de inteiro, floats, strings e os tipos Void e Bool que você vai ver mais.
Perguntas frequentes
Como você declara uma variável em Zero?
Use let. A forma é let nome = valor para um tipo inferido, ou let nome: Tipo = valor para escrever o tipo explicitamente. Por exemplo: let answer = 42 ou let answer: i32 = 42. Os dois ligam o nome answer ao valor 42 no escopo atual.
Zero infere tipos para ligações let?
Sim. Se você escreve let total = sum(point) e sum retorna i32, o tipo da ligação é inferido como i32. Você ainda pode anotar explicitamente quando quer documentar o tipo ou forçar um específico — por exemplo let count: u8 = 10.
Ligações let em Zero são mutáveis?
Um let simples introduz uma ligação local para uso dentro do escopo. A história da mutabilidade no Zero pré-1.0 ainda está evoluindo — a linguagem enfatiza efeitos explícitos e memória previsível, então qualquer coisa que mute estado por uma ligação tem que tornar isso visível. Confira a documentação atual do Zero para a sintaxe exata de mutabilidade na versão da sua toolchain.
Qual a diferença entre let e const em Zero?
Zero usa let para ligações locais comuns dentro de corpos de função. Não expõe múltiplas palavras-chave de ligação como let/const/var do JavaScript — manter a superfície pequena é uma escolha de design deliberada. Constantes de tempo de compilação são tipicamente expressas pelo sistema de tipos ou por declarações no nível superior, não por uma palavra-chave separada.
Você pode redeclarar uma ligação let em Zero?
Ligações vivem dentro do escopo que as contém. Um novo let com o mesmo nome num escopo aninhado é uma ligação separada que sombreia a externa durante o escopo interno — a ligação externa não é afetada depois que o escopo interno termina. É o mesmo modelo de Rust e das linguagens da família ML.