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
- exhaustivité vérifiée au moment de la compilation
- Plusieurs articles par bras :
1, 2 => ...
- Bras de portée :
0...10 => ...
- Noms des broches de capture :
inline else => \|tag\| ...
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 |
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
comptime les blocs s'exécutent pendant la compilation
comptime les paramètres de la fonction sont connus au moment de la compilation
inline for / inline while dérouler les boucles au moment du concours
@Type(...) construire des types à comptime
@fieldParentPtr recherche de champ inversée
@hasDecl @hasField réflexion au moment de la compilation
@typeInfo obtient les informations de type sous forme de structure
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
- Chaque allocation prend un paramètre d'allocateur explicite
- Pas d'allocateur global, pas d'allocations implicites
- Les répartiteurs composent (pool → arène → page)
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
- Pas de préprocesseur (utilisez
comptime)
- Aucune conversion implicite (explicite
@intCast @floatCast)
- Pas d'UB par défaut (contrôles de sécurité lors du débogage, opt-in
@setRuntimeSafety)
defer remplace goto cleanup modèles
anytype remplace void* + macro génériques
- Le type de tableau inclut la longueur (
[N]T vs T[N])
undefined au lieu de non initialisé
null d'optionnel ?*T, pas un pointeur
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 |