Enums
Le mot-clé enum déclare un type avec un ensemble fini de variantes nommées :
enum Color { red; green; blue }
Chaque variante est un identifiant séparé par ;. L'accès se fait par qualification : Color.red, Color.green,
Color.blue.
enum Color { red; green; blue }
c = Color.red
print(c)
# → Color.red
Accès aux variantes
Les variantes sont toujours qualifiées par le nom de l'enum. red seul ne désigne rien -- c'est Color.red qui produit
la valeur.
enum Direction { up; down; left; right }
d = Direction.left
print(d)
# → Direction.left
Accéder à une variante inexistante lève une erreur :
enum Color { red; green; blue }
Color.yellow # Erreur : 'Color' has no variant 'yellow'
Enums multiples
Plusieurs enums coexistent dans le même scope. Des noms de variantes identiques dans des enums distincts ne créent aucun conflit : la qualification lève l'ambiguité.
enum Color { red; blue }
enum Direction { up; down }
Color.red != Direction.up
# → True
enum A { x; y }
enum B { x; y }
A.x != B.x
# → True
Deux variantes portant le même nom dans deux enums différents n'ont rien en commun. La cohabitation est purement syntaxique.
Egalite
Deux variantes du même enum sont égales si et seulement si elles désignent la même variante. Deux variantes d'enums différents ne sont jamais égales, même si elles portent le même nom.
enum Color { red; green; blue }
Color.red == Color.red
# → True
Color.red == Color.blue
# → False
Color.red != Color.blue
# → True
enum A { x }
enum B { x }
A.x == B.x
# → False
Truthiness
Toutes les variantes d'enum sont truthy. Aucune n'est falsy.
enum Color { red; green; blue }
if Color.red { "oui" } else { "non" }
# → "oui"
Pattern matching
Les variantes d'enum s'utilisent comme patterns dans un match. La syntaxe est identique à l'accès : Enum.variante.
enum Color { red; green; blue }
c = Color.green
match c {
Color.red => { "rouge" }
Color.green => { "vert" }
Color.blue => { "bleu" }
}
# → "vert"
Le wildcard _ fonctionne normalement :
enum Color { red; green; blue }
c = Color.blue
match c {
Color.red => { "rouge" }
_ => { "autre" }
}
# → "autre"
Attention : un identifiant nu (sans qualification) dans un pattern match est une capture de variable, pas un test
de variante. red capture la valeur dans une variable red ; Color.red teste l'égalité avec la variante.
enum Color { red; green; blue }
match Color.blue {
red => { "piege" } # capture dans 'red', matche toujours
_ => { "jamais" }
}
# → "piege" (red est un binding, pas Color.red)
Pour matcher une variante, toujours qualifier : Color.red.
Erreurs
Un enum vide est interdit :
enum Empty { } # Erreur de syntaxe
Les variantes dupliquées sont interdites :
enum Bad { a; a } # Erreur : variante dupliquée
Limitations (v1)
La version actuelle des enums couvre les cas d'usage les plus courants. Les fonctionnalités suivantes ne sont pas supportées :
- Pas de payload : les variantes ne portent pas de données (
Option.Some(42)n'existe pas) - Pas de méthodes : on ne peut pas définir de fonctions sur un enum
- Pas d'héritage : pas de
extendspour les enums - Pas de traits : pas de
implementspour les enums
Enum vs Struct
| Propriété | enum |
struct |
|---|---|---|
| Contenu | Variantes nommées | Champs typés |
| Instanciation | Color.red |
Point(1, 2) |
| Mutation | Non (valeur fixe) | Oui (p.x = 5) |
| Méthodes | Non | Oui |
| Héritage | Non | Oui (extends) |
| Traits | Non | Oui (implements) |
| Pattern matching | Color.red => { ... } |
Point{x, y} => { ... } |
| Egalité | Même variante = égal | Même champs = égal |
| Truthiness | Toujours truthy | Toujours truthy |
Les enums sont des constantes nommées avec un type. Les structs sont des conteneurs avec des champs. Les deux se matchent, mais l'un bouge et l'autre pas.