Panoramica del linguaggio Zig
Zig 0.14 — linguaggio di sistema | nessun flusso di controllo nascosto | nessuna allocazione nascosta | nessun preprocessore | esecuzione in fase di compilazione
Paradigma
Imperativo, procedurale, orientato ai dati. Tipizzazione statica con inferenza, tipizzazione strutturale (duck) tramite comptime. Compilazione tramite LLVM + backend self-hosted. Nessun sovraccarico dell'operatore, nessuna eccezione, nessun RAII, nessuna macro.
Tipi
| Categoria |
Tipi |
| Firmato int |
i8 i16 i32 i64 i128 isize |
| Intero non firmato |
u8 u16 u32 u64 u128 usize |
| Galleggiante |
f16 f32 f64 f128 |
| Bool |
bool |
| Vuoto |
void |
| Mai |
noreturn |
| Matrice |
[N]T |
| Fetta |
[]T |
| Puntatore |
*T *const T [*]T (molti articoli) [*c]T (puntatore C) |
| Facoltativo |
?T |
| Errore di unione |
E!T |
| Struttura |
struct { field: T } |
| Unione |
union { field: T } (contrassegnato) |
| Enum |
enum { variant } |
| Imballato union/enum |
packed union packed enum |
| Vettore |
@Vector(N, T) (SIMD) |
| Funzione |
fn(params) ReturnType |
| Opaco |
opaque {} |
| Comptime |
comptime T (noto in fase di compilazione) |
| Qualsiasi tipo |
anytype (digitazione duck comptime) |
| Qualsiasi errore |
anyerror |
| Digitare |
type (tipo di prima classe) |
| Vuoto (zero bit) |
comptime void |
Dichiarazioni
| Costruisci |
Sintassi |
Note |
| Funzione |
fn name(params) ReturnType { body } |
|
| Variabile |
const x = expr; |
Immutabile |
| Mutevole |
var x = expr; |
|
| Costante |
const NAME: T = expr; |
Conosciuto al momento dell'acquisto |
| Esportazione |
export fn name() void { ... } |
Visibile al linker |
| Esterno |
extern fn name() void; |
Da un altro oggetto |
| Struttura |
const T = struct { field: T }; |
|
| Enum |
const E = enum { variant }; |
|
| Unione |
const U = union(enum) { field: T }; |
Taggato unione |
| Errore impostato |
const Errors = error { E1, E2 }; |
|
| Prova |
test "name" { ... } |
|
| Blocco del tempo libero |
comptime { ... } |
|
| Assemblaggio in linea |
asm volatile ("code"); |
|
| Importa |
const std = @import("std"); |
|
Flusso di controllo
| Costruisci |
Sintassi |
Note |
| Se |
if (cond) { ... } else { ... } |
|
| Se (espressione) |
const x = if (cond) a else b; |
|
| Se (facoltativo) |
if (opt) |val| { ... } else { ... } |
Cattura scarta |
| Se (errore di unione) |
if (result) |val| { ... } else |err| { ... } |
|
| Mentre |
while (cond) { ... } |
|
| Mentre (facoltativo) |
while (opt) |val| { ... } |
|
| Mentre (errore) |
while (result) |val| { ... } else |err| { ... } |
|
| Per |
for (slice) |item| { ... } |
|
| Per (indice) |
for (slice, 0..) |item, i| { ... } |
|
| Cambia |
switch (expr) { variant => body, else => body } |
Esauriente |
| Pausa |
break; |
|
| Continua |
continue; |
|
| Ritorno |
return expr; |
|
| Differire |
defer expr; |
Esegui all'uscita dall'ambito |
| Errdefer |
errdefer expr; |
Esegui in caso di errore |
| Cattura |
result catch |err| { ... } |
Scartare o maneggiare |
Cambia funzionalità
- L'esaustività è stata controllata in fase di compilazione
- Articoli multipli per braccio:
1, 2 => ...
- Bracci della gamma:
0...10 => ...
- Nomi dei poli di cattura:
inline else => \|tag\| ...
Operatori
| Categoria |
Operatori |
| Aritmetica |
+ - * / % |
| Avvolgimento |
+% -% *% |
| Saturazione |
+| -| *| |
| Confronto |
== != < > <= >= |
| Logico |
and or ! |
| Bit per bit |
>> << & | ^ ~ |
| Composto |
+= -= *= /%= &= |= ^= <<= >>= |
| Nullabile |
orelse catch .? (scartare opzionale) |
| Varie |
.. (intervallo) ** (ptr deref multi) . (campo) .* (ptr deref) |
| Indirizzo di |
&expr |
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
comptime {
// Runs at compile time
@compileLog("building for", @tagName(builtin.cpu));
}
// Generics via comptime parameters
fn ArrayList(comptime T: type) type {
return struct {
items: []T,
fn init(self: *Self) void { ... }
};
}
Funzionalità di tempo libero
comptime i blocchi vengono eseguiti durante la compilazione
comptime i parametri della funzione sono noti in fase di compilazione
inline for / inline while srotola i loop in fase di comptime
@Type(...) costruire tipi in comptime
@fieldParentPtr ricerca inversa sul campo
@hasDecl @hasField riflessione in fase di compilazione
@typeInfo ottiene informazioni sul tipo come struttura
Memoria
| Operazione |
Sintassi |
Note |
| Assegnare |
allocator.alloc(T, n) |
Restituisce ![]T |
| Gratuito |
allocator.free(slice) |
|
| Rialloc |
allocator.realloc(slice, n) |
|
| Crea |
allocator.create(T) |
Elemento singolo |
| Distruggi |
allocator.destroy(ptr) |
|
| Parametro ripartitore |
allocator: Allocator |
Sempre esplicito |
Allocatori
std.heap.page_allocator std.heap.arena_allocator std.heap.FixedBufferAllocator std.heap.ArenaAllocator std.heap.StackFallbackAllocator std.heap.c_allocator
La filosofia dell'allocatore di Zig
- Ogni allocazione accetta un parametro allocatore esplicito
- Nessun allocatore globale, nessuna allocazione implicita
- I ripartitori compongono (pool → arena → pagina)
Gestione degli errori
// Error union type: ReturnType!Error
fn div(a: i32, b: i32) !i32 {
if (b == 0) return error.DivisionByZero;
return a / b;
}
// Try operator: early return on error
const result = try div(10, 2);
// Catch: provide default
const val = div(10, 0) catch 0;
// Global error set vs specific
fn parse() ParseError!i32 { ... }
Differire e Errdefer
{
const buf = try allocator.alloc(u8, 100);
defer allocator.free(buf); // always runs at scope exit
errdefer allocator.free(buf); // runs only if error returned
// ... use buf
} // defer triggers here
Libreria standard (selezionata)
| Modulo |
Contenuto |
std.fs |
File, Dir, Percorso, cwd, readFile, writeFile, copyFile, deleteFile, makeDir, makePath |
std.io |
Lettore, scrittore, bufferizzato, formattazione, stampa |
std.net |
TcpStream, TcpListener, UdpSocket, IpAddress, DNS |
std.mem |
copia, imposta, scambia, indexOf, dividi, unisci, allocatore, interfaccia allocatore |
std.process |
ChildProcess, Args, Env, uscita, getSelfPath |
std.time |
Istantaneo, nanoTime, sonno, timer, epoca |
std.Thread |
spawn, Pool, Mutex, RwLock, Semaforo, Condizione, Atomico |
std.math |
sqrt, sin, cos, tan, exp, log, pow, addominali, min, max, pinza |
std.hash |
funzioni hash, crc32, sha256, sha512, md5 |
std.json |
analizzare, stringere, Valore, Array, Oggetto |
std.sort |
ordinamento, ricerca binaria, inserimento, unione, pdqsort |
std.unicode |
utf8, utf16, larghezza, mappatura maiuscole e minuscole |
std.Build |
Sistema di costruzione (sostituisce make/cmake) |
std.Target |
Rilevamento del target di compilazione incrociata |
std.debug |
affermare, farsi prendere dal panico, stampare, scaricare, tracciare |
Test
test "basic addition" {
try std.testing.expectEqual(4, add(2, 2));
try std.testing.expect(add(1, 1) == 2);
try std.testing.expectError(error.DivisionByZero, div(1, 0));
}
zig test file.zig # run tests
zig build test # run all tests in project
zig test --name "filter" # filter test names
Compilazione incrociata
zig build-exe main.zig --target x86_64-windows # cross-compile to Windows
zig build-exe main.zig --target aarch64-linux # cross-compile to ARM64 Linux
zig build-exe main.zig --target riscv64-linux # cross-compile to RISC-V
Zig viene fornito con intestazioni libc e toolchain di compilazione incrociata per tutti i principali target: non è necessario un compilatore incrociato separato.
Interoperabilità C
// Import C header
const c = @cImport({
@cInclude("stdio.h");
});
// Link C library
pub fn main() void {
_ = c.printf("hello %d\n", 42);
}
// Direct use of C ABI
extern "c" fn strlen(s: [*:0]u8) usize;
// Zig is a better C:
// - @cImport for headers
// - export fn for C-ABI exports
// - [*:0]T for null-terminated strings
// - @ptrCast for pointer conversion
// - packed struct for ABI-compatible layouts
Notevoli differenze rispetto a C
- Nessun preprocessore (usa
comptime)
- Nessun cast implicito (esplicito
@intCast @floatCast)
- Nessun UB per impostazione predefinita (controlli di sicurezza nel debug, attivazione
@setRuntimeSafety)
defer sostituisce goto cleanup modelli
anytype sostituisce void* + macro generici
- Il tipo di array include la lunghezza (
[N]T rispetto a T[N])
undefined anziché non inizializzato
null di facoltativo ?*T, non puntatore
Compilazione
zig build-exe main.zig # compile executable
zig build-lib lib.zig # compile library
zig build-obj obj.zig # compile object
zig run main.zig # compile + run
zig test file.zig # compile + run tests
zig fmt file.zig # format code
zig build # build project (build.zig)
zig translate-c foo.h # translate C header to Zig
Modalità di costruzione
| Modalità |
Bandiera |
Controlli di sicurezza |
Ottimizzazioni |
| Debug |
(predefinito) |
Pieno |
Nessuno |
| ReleaseSafe |
-Doptimize=ReleaseSafe |
Pieno |
Velocità |
| Rilascio veloce |
-Doptimize=ReleaseFast |
Nessuno |
Velocità |
| RilasciaPiccolo |
-Doptimize=ReleaseSmall |
Nessuno |
Misurare |