열거형

열거형 (Enumerated types / Enums)

고정된 개수의 상수 값들을 나타내야 할 때, enum이 딱 맞아요. 열거형은 종종 enumeration이나 enum이라고 불리는데, 고정된 개수의 상수 값을 표현하기 위한 특별한 종류의 클래스예요.

출처: Dart 공식 문서

본문

간단한 enum 선언 (Declaring simple enums)

간단한 열거형을 선언할 때는 enum 키워드를 쓰고, 나열하고 싶은 값들을 나열하면 돼요.

enum Color { red, green, blue }

향상된 enum 선언 (Declaring enhanced enums)

Dart는 enum 선언이 필드, 메서드, const 생성자를 가진 클래스를 선언하도록 허용해요. 다만 그 인스턴스는 고정된 개수의 알려진 상수 인스턴스로 제한돼요.

향상된 enum(enhanced enum)을 선언하려면 일반 클래스와 비슷한 문법을 따르되, 몇 가지 추가 요구사항이 있어요.

  • 인스턴스 변수는 믹스인이 추가한 것까지 포함해 모두 final이어야 해요.
  • 모든 생성자(generative constructors)는 상수여야 해요.
  • 팩토리 생성자(factory constructors)는 고정된 알려진 enum 인스턴스 중 하나만 반환할 수 있어요.
  • Enum은 자동으로 상속되므로, 다른 클래스를 상속할 수 없어요.
  • index, hashCode, 동등 연산자 ==를 오버라이드할 수 없어요.
  • values라는 이름의 멤버는 선언할 수 없어요. 자동으로 생성되는 static values 게터와 충돌하기 때문이에요.
  • enum의 모든 인스턴스는 선언의 시작 부분에 선언되어야 하고, 최소한 하나의 인스턴스가 있어야 해요.

향상된 enum의 인스턴스 메서드는 this를 사용해 현재의 enum 값을 참조할 수 있어요.

여러 인스턴스와 인스턴스 변수, 게터, 구현한 인터페이스가 있는 향상된 enum 선언 예시를 볼게요.

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;

  int get carbonFootprint => (carbonPerKilometer / passengers).round();

  bool get isTwoWheeled => this == Vehicle.bicycle;

  @override
  int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}

enum 사용하기 (Using enums)

열거된 값은 다른 static 변수처럼 접근하면 돼요.

final favoriteColor = Color.blue;
if (favoriteColor == Color.blue) {
  print('Your favorite color is blue!');
}

enum의 각 값에는 index 게터가 있어요. 이 게터는 enum 선언에서 값의 0부터 시작하는 위치를 반환해요. 예를 들어 첫 번째 값은 index 0, 두 번째 값은 index 1이에요.

assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);

모든 열거 값을 리스트로 얻으려면 enum의 values 상수를 쓰면 돼요.

List<Color> colors = Color.values;
assert(colors[2] == Color.blue);

enum은 switch 문에서 쓸 수 있고, enum의 모든 값을 다루지 않으면 경고가 나와요.

var aColor = Color.blue;

switch (aColor) {
  case Color.red:
    print('Red as roses!');
  case Color.green:
    print('Green as grass!');
  default: // Without this, you see a WARNING.
    print(aColor); // 'Color.blue'
}

열거 값의 이름을 가져오고 싶을 때, 예를 들어 Color.blue에서 'blue' 같은 문자열이 필요하다면 .name 속성을 쓰면 돼요.

print(Color.blue.name); // 'blue'

enum 값의 멤버는 일반 객체처럼 접근할 수 있어요.

print(Vehicle.car.carbonFootprint);

더 알아보기 (Learn more)