- O Zig se baseia em uma sintaxe com chaves semelhante à do Rust, mas a melhora com uma semântica de linguagem mais simples e escolhas sintáticas mais refinadas
- Literais inteiros começam todos com o tipo
comptime_int e são convertidos explicitamente na atribuição, enquanto literais de string usam uma notação concisa de string bruta baseada em \\
- Literais de registro no formato
.x = 1 facilitam a busca por escritas em campos, e todos os tipos são expressos de forma consistente com notação de prefixo
and e or são usados como palavras-chave de controle de fluxo, e construções if e loop podem opcionalmente omitir chaves, com o formatador garantindo a segurança
- Sem namespaces, tudo é tratado como expressão, unificando a sintaxe de tipos, valores e padrões, e usando de forma concisa genéricos, literais de registro e funções embutidas (
@import, @as etc.)
Visão geral
- O Zig tem uma aparência semelhante à do Rust, mas adota uma estrutura de linguagem mais simples
- No design da sintaxe, o foco está em facilidade para grep, consistência sintática e redução de ruído visual desnecessário
Literais inteiros
const an_integer = 92;
assert(@TypeOf(an_integer) == comptime_int);
const x: i32 = 92;
const y = @as(i32, 92);
- Todos os literais inteiros têm o tipo
comptime_int
- Ao atribuir a uma variável, é preciso declarar o tipo explicitamente ou converter com
@as
- A forma
var x = 92; não funciona; é necessário um tipo explícito
Literais de string
const raw =
\\Roses are red
\\ Violets are blue,
\\Sugar is sweet
\\ And so are you.
\\
;
- Cada linha é um token separado, então não há problema com indentação
- Não é necessário escapar o próprio
\\
Literais de registro
const p: Point = .{
.x = 1,
.y = 2,
};
- O formato
.x = 1 é vantajoso para distinguir leitura e escrita
- A notação
.{} se diferencia de blocos e faz conversão automática para o tipo de resultado
Notação de tipos
u32 // inteiro
[3]u32 // array de tamanho 3
?[3]u32 // array anulável
*const ?[3]u32 // ponteiro constante
- Todos os tipos usam notação de prefixo
- A desreferenciação usa notação de sufixo (
ptr.*)
Identificadores
const @"a name with space" = 42;
- É possível evitar conflito com palavras-chave ou definir nomes especiais
Declaração de funções
pub fn main() void {}
fn add(x: i32, y: i32) i32 {
return x + y;
}
- A palavra-chave
fn fica colada ao nome da função, facilitando a busca
- Não se usa
-> para indicar o tipo de retorno
Declaração de variáveis
const mid = lo + @divFloor(hi - lo, 2);
var count: u32 = 0;
- Usa
const e var
- A notação de tipo segue a ordem
nome: tipo
Controle de fluxo: and/or
while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {
count -= 1;
}
and e or são palavras-chave de controle de fluxo
- Para operações bit a bit, usam-se
& e |
Instrução if
.direction = if (prng.boolean()) .ascending else .descending;
- Parênteses são obrigatórios; chaves são opcionais
- O
zig fmt garante uma formatação segura
Laços
for (0..10) |i| {
print("{d}\n", .{i});
} else @panic("loop safety counter exceeded");
- Tanto
for quanto while aceitam cláusula else
- O iterador e o nome do elemento são posicionados de forma intuitiva
Namespaces e resolução de nomes
const std = @import("std");
const ArrayList = std.ArrayList;
- Sombreamento de variáveis é proibido
- Não há namespaces nem importações globais
Tudo é expressão
const E = enum { a, b };
const e: if (true) E else void = .a;
- Unifica a sintaxe de tipos, valores e padrões
- É possível colocar expressões condicionais na posição de tipo
Genéricos
fn ArrayListType(comptime T: type) type {
return struct {
fn init() void {}
};
}
var xs: ArrayListType(u32) = .init();
- Os genéricos são expressos com sintaxe de chamada de função (
Type(T))
- Os argumentos de tipo são sempre explícitos
Funções embutidas
const foo = @import("./foo.zig");
const num = @as(i32, 92);
- Recursos fornecidos pelo compilador são chamados com o prefixo
@
@import mostra claramente o caminho do arquivo
- Os argumentos devem ser obrigatoriamente literais de string
Conclusão
- A sintaxe do Zig é um caso em que um conjunto de pequenas escolhas se junta para criar uma linguagem agradável de ler
- Quando se reduz o número de recursos, também se reduz a sintaxe necessária e a chance de conflito entre construções sintáticas
- Ele aproveita boas ideias de linguagens existentes, mas introduz nova sintaxe sem medo quando necessário
Ainda não há comentários.