O tipo enumerado é uma classe especial usada para representar um conjunto com quantidade fixa de valores constantes.
Todas as enumerações herdam automaticamente da classe Enum. Além disso, enumerações são tipos selados (sealed): não podem ser herdadas, implementadas, misturadas nem instanciadas explicitamente de forma manual.
Classes abstratas e mixins podem implementar ou herdar explicitamente Enum, mas não é possível criar objetos concretos dessa classe ou mixin, a menos que uma enumeração declare sua implementação ou inclusão.
Use a palavra-chave enum e liste todas as constantes para definir uma enumeração simples:
enum Color { red, green, blue }
É permitido adicionar vírgula no final ao declarar uma enumeração; isso facilita cópia e cola e reduz falhas no código.
Enumerações aprimoradas (Enhanced enums)
O Dart suporta enumerações aprimoradas. Você pode definir campos membros, métodos e construtores constantes como em classes comuns, mas as instâncias só podem ser as constantes fixas predefinidas.
Declarar uma enumeração aprimorada segue uma série de regras obrigatórias:
- Variáveis de instância devem ser marcadas como
final(incluindo variáveis trazidas por mixins) - Todos os construtores geradores precisam receber a marcação
const - Construtores de fábrica só podem retornar instâncias constantes já definidas dentro da enumeração
- Não há possibilidade de herdar explicitamente outra classe (a herança de
Enumocorre automaticamente) - Não se pode sobrescrever
index,hashCodee o operador de igualdade== - Não declare membros com nome
valuesna enumeração, pois entra em conflito com o acessador estáticovaluesgerado automaticamente - Todas as instâncias da enumeração devem ser escritas no início da definição, sendo obrigatório ter ao menos uma instância
- Nos métodos de instância de enumerações aprimoradas, use
thispara se referir à constante da enumeração atual
Exemplo
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;
}Code language: Dart (dart)
A partir do Dart 3.13, os construtores principais simplificam a escrita das enumerações aprimoradas:
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;
}Code language: Dart (dart)
Utilizando enumerações
Acesse constantes de enumeração da mesma forma que variáveis estáticas:
final favoriteColor = Color.blue;
if (favoriteColor == Color.blue) {
print('Sua cor favorita é o azul!');
}Code language: Dart (dart)
Propriedade index
Cada constante da enumeração tem a propriedade index, que retorna o número de ordem iniciado em 0 dentro da definição:
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);Code language: Dart (dart)
Constante estática values
Obtenha uma lista com todos os valores da enumeração através de NomeEnum.values:
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);Code language: Dart (dart)
Usando enumeração com switch
Ao utilizar enumeração em um switch, o compilador emitirá um aviso caso nem todos os ramos estejam cobertos. Você pode usar default para cobrir casos restantes.
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print('Vermelho como rosas!');
case Color.green:
print('Verde como grama!');
default:
print(aColor); // Color.blue
}Code language: Dart (dart)
Propriedade name
Recupere o nome textual correspondente à constante por meio de .name:
print(Color.blue.name); // Exibe "blue"Code language: Dart (dart)
Acessando membros personalizados da enumeração
Em enumerações aprimoradas, acesse campos, getters e métodos próprios exatamente como objetos comuns:
print(Vehicle.car.carbonFootprint);Code language: CSS (css)
Abaixo segue um exemplo completo desta aula. Vamos criar uma enumeração para meses e aplicar todos os conceitos estudados.
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});
/// Número do mês gregoriano, de 1 a 12
final int monthNumber;
/// Nome
final String cnName;
/// Dias no ano comum
final int days;
/// Getter: Pertence ao primeiro trimestre?
bool get isFirstQuarter => monthNumber <= 3;
/// Getter: Tem 31 dias?
bool get has31Days => days == 31;
/// Método personalizado: Verifica se fevereiro é de ano bissexto
bool isLeapYearFebruary(int year) {
if (this != Month.february) return false;
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
/// Implementa Comparable para ordenação
@override
int compareTo(Month other) {
return monthNumber - other.monthNumber;
}
}
void main() {
// 1. Acesso básico às constantes da enumeração
Month current = Month.august;
print('Enumeração atual: $current');
print('Propriedade name da enumeração: ${current.name}');
print('Mês: ${current.cnName}');
print('Número do mês 1~12: ${current.monthNumber}');
print('Dias no ano comum: ${current.days}');
print('É mês de 31 dias? ${current.has31Days}');
print('Pertence ao primeiro trimestre? ${current.isFirstQuarter}');
// 2. Propriedade index (índice de declaração, começa em 0)
print('\n${Month.january.name} index = ${Month.january.index}');
print('${Month.december.name} index = ${Month.december.index}');
// 3. values para listar todos os meses
List<Month> allMonths = Month.values;
print('\nExistem ${allMonths.length} meses no total');
// 4. Utilizando switch com enumeração
print('\n==== Teste switch ====');
switch (current) {
case Month.january:
print('Início do ano');
case Month.february:
print('Pode ter dia bissexto');
case Month.march:
case Month.april:
case Month.may:
print('Primavera');
case Month.june:
case Month.july:
case Month.august:
print('Verão');
case Month.september:
case Month.october:
case Month.november:
print('Outono');
case Month.december:
print('Inverno, fim de ano');
}
// 5. Chamando método personalizado
Month feb = Month.february;
print('\nFevereiro de 2024 é ano bissexto? ${feb.isLeapYearFebruary(2024)}');
print('Fevereiro de 2025 é ano bissexto? ${feb.isLeapYearFebruary(2025)}');
// 6. Ordenar enumerações (via interface Comparable)
var selected = [Month.october, Month.january, Month.july];
selected.sort();
print('\nMeses ordenados: ${selected.map((m) => m.cnName).toList()}');
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Enumeração atual: Month.august
Propriedade name da enumeração: august
Mês: 八月
Número do mês 1~12: 8
Dias no ano comum: 31
É mês de 31 dias? true
Pertence ao primeiro trimestre? false
january index = 0
december index = 11
Existem 12 meses no total
==== Teste switch ====
Verão
Fevereiro de 2024 é ano bissexto? true
Fevereiro de 2025 é ano bissexto? false
Meses ordenados: [一月, 七月, 十月]Code language: JavaScript (javascript)
Enumerações