Le type énuméré est une classe spéciale destinée à représenter un ensemble de valeurs constantes en nombre fixe.
Toutes les énumérations héritent automatiquement de la classe Enum. Par ailleurs, une énumération est un type scellé (sealed) : il ne peut pas être hérité, implémenté, mixé, ni instancié explicitement manuellement.
Les classes abstraites et les mixins peuvent implémenter ou hériter explicitement de Enum, mais il est impossible de créer des instances concrètes de ces classes ou mixins, à moins qu’une énumération ne déclare leur implémentation ou leur intégration.
Utilisez le mot-clé enum et listez toutes les constantes de l’énumération pour définir une énumération simple :
enum Color { red, green, blue }
Une virgule finale est autorisée lors de la déclaration d’une énumération ; cela facilite le copier-coller et limite les erreurs de code.
Énumérations améliorées (Enhanced enums)
Dart prend en charge les énumérations améliorées. Vous pouvez y définir des champs membres, des méthodes et des constructeurs constants comme dans une classe classique, mais ses instances ne peuvent être que les constantes fixes prédéfinies.
La déclaration d’une énumération améliorée est soumise à un ensemble de règles obligatoires :
- Les variables d’instance doivent être déclarées
final(y compris celles provenant des mixins) - Tous les constructeurs générateurs doivent porter le marqueur
const - Les constructeurs d’usine ne peuvent renvoyer que des instances constantes déjà définies au sein de l’énumération
- Il est interdit d’hériter explicitement d’une autre classe (l’héritage de
Enumse fait automatiquement) - Il est impossible de redéfinir
index,hashCodeet l’opérateur d’égalité== - Aucun membre nommé
valuesne peut être déclaré dans une énumération, car cela entrerait en conflit avec l’accesseur statiquevaluesgénéré automatiquement - Toutes les instances de l’énumération doivent figurer au tout début de sa définition, et au moins une instance est requise
- Dans les méthodes d’instance d’une énumération améliorée, vous pouvez utiliser
thispour faire référence à la constante d’énumération actuelle
Exemple
enum Vehicle implements Comparable<Vehicle> {
car(tires: 4, passengers: 5, carbonPerKilometer: 400),
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);
const Vehicle({
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});
final int tires;
final int passengers;
final int carbonPerKilometer;
// Getter
int get carbonFootprint => (carbonPerKilometer / passengers).round();
bool get isTwoWheeled => this == Vehicle.bicycle;
@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}Langage du code : Dart (dart)
À partir de Dart 3.13+, les constructeurs principaux simplifient la syntaxe des énumérations améliorées :
enum Vehicle(
final int tires,
final int passengers,
final int carbonPerKilometer,
) implements Comparable<Vehicle> {
car(4, 5, 400),
bus(6, 50, 800),
bicycle(2, 1, 0);
int get carbonFootprint => (carbonPerKilometer / passengers).round();
bool get isTwoWheeled => this == Vehicle.bicycle;
@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}Langage du code : Dart (dart)
Utiliser une énumération
L’accès aux constantes d’énumération s’effectue de la même manière que pour les variables statiques :
final favoriteColor = Color.blue;
if (favoriteColor == Color.blue) {
print('Votre couleur favorite est le bleu !');
}Langage du code : Dart (dart)
Propriété index
Chaque constante d’énumération possède une propriété index qui renvoie son numéro d’ordre commençant à 0 dans la définition de l’énumération :
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);Langage du code : Dart (dart)
Constante statique values
Récupérez la liste regroupant toutes les valeurs de l’énumération via NomEnumeration.values :
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);Langage du code : Dart (dart)
Associer une énumération à l’instruction switch
Lorsque vous utilisez une énumération dans un switch, le compilateur affichera un avertissement si vous ne couvrez pas toutes les branches possibles. Vous pouvez utiliser une clause default pour gérer les cas restants.
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print('Rouge comme une rose !');
case Color.green:
print('Vert comme l\'herbe !');
default:
print(aColor); // Color.blue
}Langage du code : Dart (dart)
Propriété name
Obtenez le nom de chaîne correspondant à une constante d’énumération grâce à .name :
print(Color.blue.name); // Affiche "blue"Langage du code : Dart (dart)
Accéder aux membres personnalisés de l’énumération
Sur une énumération améliorée, vous pouvez accéder aux champs, getters et méthodes personnalisés exactement comme sur un objet classique :
print(Vehicle.car.carbonFootprint);Langage du code : CSS (css)
Voici un exemple complet de cette leçon : nous allons créer une énumération pour les mois et mettre en pratique toutes les notions abordées.
enum Month implements Comparable<Month> {
january(1, '一月', days: 31),
february(2, '二月', days: 28),
march(3, '三月', days: 31),
april(4, '四月', days: 30),
may(5, '五月', days: 31),
june(6, '六月', days: 30),
july(7, '七月', days: 31),
august(8, '八月', days: 31),
september(9, '九月', days: 30),
october(10, '十月', days: 31),
november(11, '十一月', days: 30),
december(12, '十二月', days: 31);
const Month(this.monthNumber, this.cnName, {required this.days});
/// Numéro du mois du calendrier grégorien, de 1 à 12
final int monthNumber;
/// Nom
final String cnName;
/// Nombre de jours en année normale
final int days;
/// Getter : appartient au premier trimestre ?
bool get isFirstQuarter => monthNumber <= 3;
/// Getter : mois à 31 jours ?
bool get has31Days => days == 31;
/// Méthode personnalisée : vérifie si février est le mois d’une année bissextile
bool isLeapYearFebruary(int year) {
if (this != Month.february) return false;
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
/// Implémentation de Comparable pour autoriser le tri
@override
int compareTo(Month other) {
return monthNumber - other.monthNumber;
}
}
void main() {
// 1. Accès basique aux constantes d’énumération
Month current = Month.august;
print('Énumération actuelle : $current');
print('Propriété name de l\'énumération : ${current.name}');
print('Mois : ${current.cnName}');
print('Numéro du mois (1~12) : ${current.monthNumber}');
print('Nombre de jours en année normale : ${current.days}');
print('Est-ce un mois à 31 jours ? ${current.has31Days}');
print('Appartient au premier trimestre ? ${current.isFirstQuarter}');
// 2. Propriété index (indice de définition de l’énumération, débute à 0)
print('\n${Month.january.name} index = ${Month.january.index}');
print('${Month.december.name} index = ${Month.december.index}');
// 3. values pour récupérer la liste complète des énumérations
List<Month> allMonths = Month.values;
print('\nIl y a au total ${allMonths.length} mois');
// 4. Utilisation d’un switch avec une énumération
print('\n==== Test switch ====');
switch (current) {
case Month.january:
print('Début de l\'année');
case Month.february:
print('Peut comporter un jour supplémentaire en année bissextile');
case Month.march:
case Month.april:
case Month.may:
print('Printemps');
case Month.june:
case Month.july:
case Month.august:
print('Été');
case Month.september:
case Month.october:
case Month.november:
print('Automne');
case Month.december:
print('Fin de l\'année, hiver');
}
// 5. Appel de la méthode personnalisée
Month feb = Month.february;
print('\nFévrier 2024 est-il dans une année bissextile ? ${feb.isLeapYearFebruary(2024)}');
print('Février 2025 est-il dans une année bissextile ? ${feb.isLeapYearFebruary(2025)}');
// 6. Tri des énumérations (via l’interface Comparable)
var selected = [Month.october, Month.january, Month.july];
selected.sort();
print('\nMois triés : ${selected.map((m) => m.cnName).toList()}');
}Langage du code : Dart (dart)
Résultat de l’exécution
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Énumération actuelle : Month.august
Propriété name de l'énumération : august
Mois : 八月
Numéro du mois (1~12) : 8
Nombre de jours en année normale : 31
Est-ce un mois à 31 jours ? true
Appartient au premier trimestre ? false
january index = 0
december index = 11
Il y a au total 12 mois
==== Test switch ====
Été
Février 2024 est-il dans une année bissextile ? true
Février 2025 est-il dans une année bissextile ? false
Mois triés : [一月, 七月, 十月]
Énumérations