Les types intégrés
Zero vous donne un ensemble petit et régulier de types primitifs. Rien d'exotique, rien de surprenant — juste ceux dont chaque langage système a besoin, nommés de façon cohérente.
| Famille | Types | Notes |
|---|---|---|
| Entiers signés | i8, i16, i32, i64 | Complément à deux. |
| Entiers non signés | u8, u16, u32, u64 | 0 et positif uniquement. |
| Taille du pointeur | usize, isize | Largeur égale à celle du pointeur de la plateforme. |
| Flottants | f32, f64 | IEEE-754. |
| Booléen | bool | true ou false. |
| Caractère | char | Une seule valeur scalaire Unicode. |
| Chaîne | String | Chaîne UTF-8. |
| Vide | Void | « Pas de valeur utile. » |
C'est la liste complète des primitifs que vous toucherez au quotidien. Les types composés — shapes, enums, choices — se construisent à partir de ceux-là.
Entiers
Les types entiers suivent un schéma de nommage uniforme : i pour signé, u pour non signé, suivi de la largeur en bits. Donc i32 est un entier signé 32 bits ; u8 est un octet non signé ; i64 est un entier signé 64 bits.
let small_signed: i8 = -120
let byte: u8 = 250
let id: i32 = 1
let big: i64 = 9_000_000_000
let index: usize = 0
La valeur par défaut pour un littéral sans suffixe est i32, sauf si le contexte environnant force autre chose :
let answer = 42 // i32
Quand vous avez besoin d'une largeur précise, attachez un suffixe au littéral ou annotez la liaison :
let byte = 250_u8 // littéral typé
let byte: u8 = 250 // liaison typée
Les deux formes produisent la même valeur. La forme suffixée sur le littéral est pratique quand vous passez un littéral directement à une fonction ou que vous construisez un struct :
let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }
Quand choisir quelle largeur
Une règle de pouce courte :
i32pour la plupart des maths signées. Assez large pour quasiment tout ce que vous comptez, rapide sur toute plateforme.u8pour le travail au niveau octet. Octets d'un fichier, octets dans un tampon, octets sur le réseau.u32/u64pour des comptes non négatifs quand la plage compte. Décalages de fichier au-delà de 2 Go, gros comptes.usizepour les tailles et les indices. Taille du pointeur — correspond à ce que la plateforme utilise pour adresser la mémoire.i64pour le temps-depuis-l'époque et similaires. Assez grand pour des nanosecondes pendant des centaines d'années.
Choisir le plus petit type qui convient est une bonne pratique ; choisir un type trop petit et déborder est un problème bien plus grave que de prendre un type un brin trop large.
Booléens
let ok = true
let done: bool = false
bool a exactement deux valeurs : true et false. Ce sont des littéraux, pas des constantes que vous importez de quelque part. La condition d'un if ou d'un while est un bool — il n'y a pas de coercition implicite vers la vérité pour les entiers ou les chaînes.
if ok {
check world.out.write("yes\n")
} else {
check world.out.write("no\n")
}
If/else couvre les conditionnels en détail.
Flottants
f32 et f64 sont des nombres à virgule flottante IEEE-754 sur 32 et 64 bits respectivement. Utilisez-les quand vous avez besoin de valeurs fractionnaires — mesures, ratios, géométrie. Pour de l'arithmétique exacte sur la monnaie, préférez les entiers dans la plus petite unité (centimes, satoshis) aux flottants.
let ratio: f32 = 0.5
let pi: f64 = 3.141592653589793
f64 est le défaut pour un littéral flottant sans suffixe.
Caractères et chaînes
Un char contient une seule valeur scalaire Unicode :
let initial: char = 'Z'
Une String est une séquence de caractères, typiquement encodée en UTF-8 par la bibliothèque standard. Les littéraux de chaîne utilisent les guillemets droits doubles :
let message: String = "hello from zero\n"
Les séquences d'échappement attendues fonctionnent — \n pour le saut de ligne, \t pour la tabulation, \\ pour un antislash littéral, \" pour un guillemet double littéral.
let multi_line = "line one\nline two\n"
La bibliothèque standard expose des vues au niveau octet sur une chaîne pour le travail bas niveau. La forme std.mem.span("zero") retourne un Span<u8> sur les octets — utile quand vous parsez, hachez ou comparez octet par octet.
Void
Void est le type « pas de valeur de retour utile » de Zero. Les fonctions qui existent pour leurs effets de bord l'utilisent :
pub fun main(world: World) -> Void raises {
check world.out.write("hello\n")
}
main écrit quelque chose et retourne. Il n'y a pas de valeur à rendre, donc le type est Void. Vous verrez Void sur la plupart des fonctions qui touchent à World — elles sont choisies pour leur effet, pas pour leur résultat.
Soulignements dans les littéraux numériques
Les longs littéraux numériques peuvent utiliser des soulignements comme séparateurs visuels. Le compilateur les ignore, donc c'est une pure fonctionnalité de lisibilité :
let big = 9_000_000_000_i64
let bytes = 1_048_576_u32 // 1 MiB
Placez-en partout où les chiffres deviennent durs à dénombrer.
Aide-mémoire des suffixes de littéraux typés
| Suffixe | Type | Exemple |
|---|---|---|
_i8 / _i16 / _i32 / _i64 | Entier signé | 127_i8 |
_u8 / _u16 / _u32 / _u64 | Entier non signé | 255_u8 |
_usize / _isize | Taille du pointeur | 0_usize |
_f32 / _f64 | Flottant | 0.5_f32 |
Sortez-en un quand vous construisez une valeur et que le contexte environnant ne fixe pas le type.
La suite : les fonctions
Les primitifs ne servent à rien sans quelque chose à en faire. Le prochain document couvre les fonctions en Zero — comment les déclarer, en retourner des valeurs, et les assembler pour construire de vrais programmes.
Questions fréquentes
Quels types primitifs propose Zero ?
Zero embarque des entiers signés de tailles fixes i8, i16, i32, i64 ; des entiers non signés u8, u16, u32, u64 ; des entiers à la taille du pointeur usize et isize ; les flottants f32 et f64 ; bool ; char ; String ; et Void pour les fonctions qui ne retournent rien d'utile.
Quel est le type entier par défaut en Zero ?
Un littéral entier sans suffixe comme 42 est par défaut un i32 à moins que le contexte ne force un autre type. Pour utiliser une largeur précise, écrivez le littéral avec un suffixe comme 42_u8 ou 42_i64, ou annotez le type de la liaison explicitement avec let count: u8 = 42.
Zero possède-t-il un type chaîne dédié ?
Oui. Les littéraux de chaîne comme "hello" ont un type chaîne intégré que la bibliothèque standard traite comme une séquence d'octets (souvent en UTF-8). Pour du travail bas niveau sur les octets, la bibliothèque standard expose des spans et des utilitaires au niveau octet ; pour les opérations au niveau caractère, il y a char pour les valeurs scalaires individuelles.
Que signifie Void en Zero ?
Void est le type de retour d'une fonction qui ne produit pas de valeur utile — elle n'existe que pour ses effets de bord. La signature conventionnelle pub fun main(world: World) -> Void raises utilise Void parce que main existe pour faire des E/S et sortir, pas pour produire une valeur.
Quelle est la différence entre i32 et u32 en Zero ?
i32 est un entier signé 32 bits dont la plage va de −2 147 483 648 à 2 147 483 647. u32 est non signé et va de 0 à 4 294 967 295. Utilisez les types signés quand les valeurs négatives ont un sens, non signés quand des valeurs négatives seraient un bug — pour des compteurs, des index, des tailles, etc.