본문 바로가기
Flutter/Dart

Enum이 뭐고, Enhanced Enum은 왜 쓸까?

by 복복씨 2024. 8. 12.

Enum

- 열거형, Enum에 있는것들은 상수다.

- 유한한 상수 집합이라는 특징을 가지고 있다.

- UpperCamelCase로 작성해야됨 

enum Color { red, green, blue }

 

Color.red : 이 자체가 Color type값 

Color.red.name : red 라는 String (String 값이 필요하면 name으로 읽으면 됨) 

Color.red.index : red 가 위치한 index, 0부터 시작 

Color.vlaues : iterable하게 enum을 쓸 수  있다. list화 시켜주는거임 

 

map,list 와 달리 enum을 쓰는 이유
list. map은 리스트 맵이 나열된 값을 쓰는 경우가 꽤 많은데, 이런 일반적인 Map,list를 쓰면 개발자가 '해석'해야됨 (비용 낭비죠) enum을 쓰면 좀 더 명확하게 알 수 있어요. 

 

 

Enhanced enum

- constructor, method 사용가능 , const constructor 필수다 

enum Vehicle {
 car(tires: 4, passengers: 5);
 
 // porperty 선언: 반드시 final로 선언해야 함
 fianl int tires;
 final int passengers;
 
 //Constructor, const필수
 const Vehicle({
  required this.tires,
  required this.passengers
 });
 
 //속성으로 값을 쓸 때 Enum에서 method를 많이 쓴다.
 String get isMultiPassenger => (passengers >=2 ) ? "가능" : "불가능";
}

 

 

근데 이걸.. 왜 쓸까?

그냥 class쓰면 안될까? 왜 굳이 enhanced Enum을 쓸까.

결국 개념이 뚜렷한 enum을 사용함으로써 비용절감을 하기위함 아닐까 생각해본다.. 길게 풀어서 설명해보자

 


1. 아까 말했던 개념차이
- Enum은 제한된 값의 집합을 나타내는 데 사용됨. 예를 들어, 요일, 방향(북, 남, 동, 서), 상태(성공, 실패) 등의 개념은 유한한 선택지를 가진다.  따라서 열거형은 이 제한된 값들을 표현하는 데 적합하며, 이를 사용하면 코드에서 명확하게 특정 값들만 사용된다는 의미를 전달할 수 있게 된다.
- 반면, Class는 상태와 행동을 포함하는 객체를 정의하는 데 사용되며, 특정 개념의 집합을 제한하지 않음. 클래스는 훨씬 더 복잡한 구조를 가질 수 있으며, 개념이 제한된 값 집합이 아니라는 점에서 Enum과 차이가 있음.

 

2.간결함과 명확성
Enhanced Enums는 특정 값 집합과 이 값들에 대한 동작이나 속성을 정의할 때 클래스를 사용하는 것보다 코드가 더 간결하고 명확해짐. 예를 들어, 방향(Direction)을 나타내는 enum코드를 구현해보자 ㄱㄱ 

enum Direction {
  north,
  south,
  east,
  west;

  void printDescription() {
    switch (this) {
      case Direction.north:
        print("North direction");
        break;
      case Direction.south:
        print("South direction");
        break;
      case Direction.east:
        print("East direction");
        break;
      case Direction.west:
        print("West direction");
        break;
    }
  }
}


이 예제에서 각 방향에 대한 동작을 정의하는 방법이 간단하고 직관적임. 클래스를 사용하여 동일한 기능을 구현할 수 있지만, 코드가 더 복잡해질 수 있지 않을까 싶다. 

3. switch 문에서의 사용
`enum`은 `switch` 문과 매우 잘 통합됨. Dart에서는 `switch` 문에서 `enum`의 모든 케이스를 다루지 않으면 경고를 주는 기능이 있음. 이는 코드의 안전성과 유지보수성을 높이는 데 도움이 된다 ( Swift 와 비슷하네요 )

void describe(Direction direction) {
  switch (direction) {
    case Direction.north:
    case Direction.south:
    case Direction.east:
    case Direction.west:
      print("It's a direction.");
      break;
  }
}


클래스를 사용했다면, 비슷한 패턴 매칭 기능을 구현하기 위해 더 복잡한 로직이 필요할 수 있지 않을까?

4. Enum만의 고유 기능 
Enhanced Enums는 클래스로 구현하기 어려운 몇 가지 고유한 기능을 제공한다고 한다(by ChatGPT 4o). 예를 들어, 열거형 상수 자체를 사용할 수 있는 유연성이나, 각 상수에 대해 다른 값을 연관시키는 방식 등이 있음 ( 이거 역시 굉장히 Swift와 유사하다 )

 

연관값 예제를 보며 이해하자. 

enum HttpStatus {
  ok(200, 'OK'),
  notFound(404, 'Not Found'),
  internalServerError(500, 'Internal Server Error');

  final int code;
  final String description;

  const HttpStatus(this.code, this.description);

  void handleStatus() {
    switch (this) {
      case HttpStatus.ok:
        print("Request was successful: $description");
        break;
      case HttpStatus.notFound:
        print("Error: $description");
        break;
      case HttpStatus.internalServerError:
        print("Server error: $description");
        break;
    }
  }
}

void main() {
  HttpStatus status = HttpStatus.notFound;
  status.handleStatus();
  // 출력: Error: Not Found
}

어플리케이션에서 HTTP 요청의 결과를 처리할 때, 다양한 HTTP 상태 코드에 따라 다른 행동을 해야 할 때가 있다. 고럴 때 요런 코드를 작성해 주면 조금 더 쉽게 결과 값을 낼 수 있지 않을까 싶다. 

 

+) 

Enum은 인스턴스를 생성하나?

답 : Dart의 enum은 언어 자체에서 각 항목에 대해 싱글톤 인스턴스를 생성하므로, 열거형 항목을 참조할 때마다 동일한 인스턴스에 접근하게 됩니다.

이는 enum의 각 항목이 고유하고 동일한 상태를 유지함을 보장합니다.

 


 

앞으로 플러터 앱에서 Enum을 어떤식으로 사용하게 될진 모르겠지만 개념을 확실히 짚고 감으로써 도움이 되리라 생각한다. 추가 할 내용이 있으면 천천히 추가하는 것으로 ~