- Zig repose sur une syntaxe à accolades proche de Rust, mais l’améliore avec une sémantique de langage plus simple et des choix syntaxiques plus élégants
- Les littéraux entiers commencent tous avec le type
comptime_int et sont convertis explicitement lors de l’affectation, tandis que les littéraux de chaîne utilisent une notation de chaîne brute concise basée sur \\
- Les littéraux d’enregistrement sous la forme
.x = 1 rendent les écritures de champs faciles à rechercher, et tous les types sont exprimés de manière cohérente en notation préfixée
and et or sont utilisés comme mots-clés de contrôle de flux, et les constructions if et loop peuvent omettre les accolades de manière optionnelle, le formateur garantissant la sûreté
- Sans espace de noms, tout est traité comme une expression, ce qui unifie la syntaxe des types, des valeurs et des motifs, tout en permettant d’utiliser de façon concise les génériques, les littéraux d’enregistrement et les fonctions intégrées (
@import, @as, etc.)
Vue d’ensemble
- Zig a une apparence proche de Rust, mais adopte une structure de langage plus simple
- La conception de sa syntaxe met l’accent sur la compatibilité avec grep, la cohérence syntaxique et la réduction du bruit visuel inutile
Littéraux entiers
const an_integer = 92;
assert(@TypeOf(an_integer) == comptime_int);
const x: i32 = 92;
const y = @as(i32, 92);
- Tous les littéraux entiers ont le type
comptime_int
- Lors de l’affectation à une variable, il faut soit préciser explicitement le type, soit convertir avec
@as
- La forme
var x = 92; ne fonctionne pas et nécessite un type explicite
Littéraux de chaîne
const raw =
\\Roses are red
\\ Violets are blue,
\\Sugar is sweet
\\ And so are you.
\\
;
- Chaque ligne étant un jeton distinct, il n’y a pas de problème d’indentation
- Il n’est pas nécessaire d’échapper
\\ lui-même
Littéraux d’enregistrement
const p: Point = .{
.x = 1,
.y = 2,
};
- Le format
.x = 1 facilite la distinction entre lecture et écriture
- La notation
.{} se distingue d’un bloc tout en étant automatiquement convertie vers le type de résultat
Notation des types
u32 // entier
[3]u32 // tableau de longueur 3
?[3]u32 // tableau nullable
*const ?[3]u32 // pointeur constant
- Tous les types utilisent une notation préfixée
- Le déréférencement utilise une notation suffixée (
ptr.*)
Identifiants
const @"a name with space" = 42;
- Permet d’éviter les collisions avec des mots-clés ou de définir des noms spéciaux
Déclaration de fonctions
pub fn main() void {}
fn add(x: i32, y: i32) i32 {
return x + y;
}
- Le mot-clé
fn est collé au nom de la fonction, ce qui facilite la recherche
- La notation du type de retour n’utilise pas
->
Déclaration de variables
const mid = lo + @divFloor(hi - lo, 2);
var count: u32 = 0;
- Utilise
const et var
- La notation des types suit l’ordre
nom: type
Contrôle de flux : and/or
while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {
count -= 1;
}
and et or sont des mots-clés de contrôle de flux
- Les opérations bit à bit utilisent
& et |
Instruction if
.direction = if (prng.boolean()) .ascending else .descending;
- Les parenthèses sont obligatoires, les accolades optionnelles
zig fmt garantit un formatage sûr
Boucles
for (0..10) |i| {
print("{d}\n", .{i});
} else @panic("loop safety counter exceeded");
for comme while prennent en charge une clause else
- L’itérateur et le nom de l’élément sont placés de manière intuitive
Espaces de noms et résolution des noms
const std = @import("std");
const ArrayList = std.ArrayList;
- Le masquage de variables est interdit
- Il n’y a ni espaces de noms ni imports globaux
Tout est expression
const E = enum { a, b };
const e: if (true) E else void = .a;
- Unifie la syntaxe des types, des valeurs et des motifs
- Il est possible de placer une expression conditionnelle à l’emplacement d’un type
Génériques
fn ArrayListType(comptime T: type) type {
return struct {
fn init() void {}
};
}
var xs: ArrayListType(u32) = .init();
- Les génériques sont exprimés avec une syntaxe d’appel de fonction (
Type(T))
- Les arguments de type sont toujours explicites
Fonctions intégrées
const foo = @import("./foo.zig");
const num = @as(i32, 92);
- Le préfixe
@ appelle les fonctionnalités fournies par le compilateur
@import rend clairement visible le chemin du fichier
- Les arguments doivent obligatoirement être des littéraux de chaîne
Conclusion
- La syntaxe de Zig montre comment un ensemble de petits choix peut produire un langage agréable à lire
- Réduire le nombre de fonctionnalités réduit aussi la quantité de syntaxe nécessaire, et diminue les risques de conflits syntaxiques
- Le langage emprunte les bonnes idées des langages existants, tout en introduisant sans hésiter de nouvelles formes syntaxiques lorsque c’est nécessaire
Aucun commentaire pour le moment.