Enumerações

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:

  1. Variáveis de instância devem ser marcadas como final (incluindo variáveis trazidas por mixins)
  2. Todos os construtores geradores precisam receber a marcação const
  3. Construtores de fábrica só podem retornar instâncias constantes já definidas dentro da enumeração
  4. Não há possibilidade de herdar explicitamente outra classe (a herança de Enum ocorre automaticamente)
  5. Não se pode sobrescrever index, hashCode e o operador de igualdade ==
  6. Não declare membros com nome values na enumeração, pois entra em conflito com o acessador estático values gerado automaticamente
  7. 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
  8. Nos métodos de instância de enumerações aprimoradas, use this para 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

Previous:

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *