Présentation du langage Zig

Zig 0.14 — langage système | pas de flux de contrôle caché | pas d'allocations cachées | pas de préprocesseur | exécution à la compilation

Paradigme

Impératif, procédural, orienté données. Typage statique avec inférence, typage structurel (canard) via comptime. Compilation via LLVM + backend auto-hébergé. Pas de surcharge d'opérateurs, pas d'exceptions, pas de RAII, pas de macros.

Espèces

Catégorie Espèces
Signé en entier i8 i16 i32 i64 i128 isize
Entier non signé u8 u16 u32 u64 u128 usize
Flotteur f16 f32 f64 f128
Booléen bool
Vide void
Jamais noreturn
Tableau [N]T
Tranche []T
Pointeur *T *const T [*]T (plusieurs articles) [*c]T (pointeur C)
Facultatif ?T
Union d'erreur E!T
Structure struct { field: T }
Syndicat union { field: T } (étiqueté)
Énumération enum { variant }
Emballé union/enum packed union packed enum
Vecteur @Vector(N, T) (SIMD)
Fonction fn(params) ReturnType
Opaque opaque {}
Comptime comptime T (connu au moment de la compilation)
N'importe quel type anytype (saisie canard comptime)
Toute erreur anyerror
Tapez type (type de première classe)
Vide (zéro bits) comptime void

Déclarations

Construire Syntaxe Remarques
Fonction fn name(params) ReturnType { body }
Variable const x = expr; Immuable
Mutable var x = expr;
Constante const NAME: T = expr; Connu au comptime
Exporter export fn name() void { ... } Visible sur l'éditeur de liens
Externe extern fn name() void; Depuis un autre objet
Structure const T = struct { field: T };
Énumération const E = enum { variant };
Syndicat const U = union(enum) { field: T }; Union taguée
Erreur définie const Errors = error { E1, E2 };
Tester test "name" { ... }
Bloc Comptime comptime { ... }
Assemblage en ligne asm volatile ("code");
Importer const std = @import("std");

Flux de contrôle

Construire Syntaxe Remarques
Si if (cond) { ... } else { ... }
Si (expression) const x = if (cond) a else b;
Si (facultatif) if (opt) |val| { ... } else { ... } Déballage de la capture
Si (union d'erreur) if (result) |val| { ... } else |err| { ... }
Tandis que while (cond) { ... }
Pendant que (facultatif) while (opt) |val| { ... }
Pendant que (erreur) while (result) |val| { ... } else |err| { ... }
Pour for (slice) |item| { ... }
Pour (indice) for (slice, 0..) |item, i| { ... }
Changer switch (expr) { variant => body, else => body } exhaustif
Pause break;
Continuer continue;
Retour return expr;
Différer defer expr; Exécuter à la sortie de la portée
Errdefer errdefer expr; Exécuter en cas d'erreur
Attraper result catch |err| { ... } Déballer ou manipuler

Fonctionnalités du commutateur

Opérateurs

Catégorie Opérateurs
Arithmétique + - * / %
Emballage +% -% *%
Saturation +| -| *|
Comparaison == != < > <= >=
Logique and or !
Au niveau du bit >> << & | ^ ~
Composé += -= *= /%= &= |= ^= <<= >>=
Nullable orelse catch .? (déballage en option)
Divers .. (plage) ** (ptr déréf multi) . (champ) .* (ptr déréf)
Adresse de &expr

Comptime (Métaprogrammation)

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 { ... }
    };
}

Fonctionnalités Comptime

Mémoire

Fonctionnement Syntaxe Remarques
Allouer allocator.alloc(T, n) Retours ![]T
Gratuit allocator.free(slice)
Réaffectation allocator.realloc(slice, n)
Créer allocator.create(T) Élément unique
Détruire allocator.destroy(ptr)
Paramètre d'allocateur allocator: Allocator Toujours explicite

Allocateurs

std.heap.page_allocator std.heap.arena_allocator std.heap.FixedBufferAllocator std.heap.ArenaAllocator std.heap.StackFallbackAllocator std.heap.c_allocator

La philosophie de l'allocateur de Zig

Gestion des erreurs

// 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 { ... }

Différer et reporter les erreurs

{
    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

Bibliothèque standard (sélectionnée)

Module Contenu
std.fs Fichier, Dir, Chemin, cwd, readFile, writeFile, copyFile, deleteFile, makeDir, makePath
std.io Lecteur, écrivain, tamponné, formatage, impression
std.net TcpStream, TcpListener, UdpSocket, adresse IP, DNS
std.mem copier, définir, échanger, indexOf, diviser, joindre, allocateur, interface d'allocateur
std.process ChildProcess, Args, Env, quitter, getSelfPath
std.time Instantané, nanoTime, veille, minuterie, époque
std.Thread spawn, Pool, Mutex, RwLock, Sémaphore, Condition, Atomique
std.math sqrt, sin, cos, bronzage, exp, log, pow, abs, min, max, clamp
std.hash fonctions de hachage, crc32, sha256, sha512, md5
std.json analyser, stringifier, valeur, tableau, objet
std.sort trier, recherche binaire, insertion, fusion, pdqsort
std.unicode utf8, utf16, largeur, mappage de cas
std.Build Système de construction (remplace make/cmake)
std.Target Détection de cible de compilation croisée
std.debug affirmer, paniquer, imprimer, vider, tracer

Tests

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

Compilation croisée

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 est livré avec des en-têtes libc et des chaînes d'outils de compilation croisée pour toutes les cibles principales — aucun compilateur croisé séparé n'est nécessaire.

Interopérabilité 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

Différences notables par rapport à C

Compilation

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

Modes de construction

Mode Drapeau Contrôles de sécurité Optimisations
Débogage (par défaut) Plein Aucun
Libération sécurisée -Doptimize=ReleaseSafe Plein Vitesse
Libération rapide -Doptimize=ReleaseFast Aucun Vitesse
LibérationPetite -Doptimize=ReleaseSmall Aucun Taille