티스토리 뷰
많은 프로그램 언어들이 열거형을 지원한다.
Dart도 물론 enum 타입을 사용할 수 있는데 보통 그룹화해 사용할 수 있는 상수 값들을 하나의 묶음으로 만들기 위해서 사용한다.
프로그램 언어들 마다 enum을 다양하게 활용할 수 있는 기능을 제공하는데 dart에서는 enum에 추가적인 기능을 정의할 수 없고 오직 단순한 선언과 사용만을 지원한다.
(dart 2.17부터는 enum도 일반 클래스 처럼 쉽게 기능을 정의하고 사용할 수 있게 되었다 - 본문 마지막 참고)
enum의 기본 사용법
예를 들어 아래와 같이 공지사항 게시판, 자유게시판으로 게시판이 타입이 구분된다고 가정해보자
enum을 사용하면 아래와 같이 선언해서 사용할것이다.
enum BoardType { notice, free, undefined }
아래 코드에서 문자열을 직접 비교하는 방법과 enum 타입을 비교하는 코드를 확인할 수 있다.
코드상에 문자열을 직접 사용하는 방법은 가능하면 피해야 하는 코딩 스타일이다.
특히 로직 중에 문자열을 직접 비교하는 방법은 사용하지 않는 것이 좋다.
가능하면 enum을 사용할 수 있도록 하자!!
// BAD
// board 모델에서 string타입의 type 변수를 사용할경우
if (board.type == "notice") {
...
} else if (board.Type == "free") {
.....
} else {
....
}
// GOOD
// enum 형식으로 type 변수를 사용할경우
if (board.type == BoardType.notice) {
...
} else if (board.type == BoardType.free) {
...
} else {
...
}
Dart에서 string을 enum으로 바로 변환할 수 없다.
enum을 사용하는 것이 string을 사용하는 것보다 훨씬 더 좋은 방법임은 다들 알 것이다.
하지만 dart에서는 서버 API 등에서 받은 string형식의 값을 enum으로 변환하는 별도의 기능을 제공하지 않아 string값을 enum으로 변환하는데 불편함이 있다.
서버로부터 게시판 목록을 가져오는 API에서 아래와 같은 결과를 받았다고 가정해보자.
이 응답 값을 앱에서 사용하기 위해서는 적당한 모델 클래스로 변환해야 할 것이다.
// API response - JSON
"boaders" : [
{
"id" : "notice01",
"title" : "공지사항",
"type" : "notice",
.....
},
{
"id" : "free01",
"title" : "자유게시판",
"type" : "free",
.....
},
]
이제 위 결과 값을 아래 Boader 클래스로 변환한다고 가정해보자.
Board 클래스의 type 필드는 API에서는 문자열 "notice"임으로 parseToBoardType함수와 같이 string형식의 값을 BoaderType으로 변화하는 과정이 필요하다.
// Boader Model
class Boader {
final String id;
final String title;
final BoaderType type;
}
// value를 입력받아 BoarderType으로 변환함
BoaderType parseToBoardType(String value) {
if (value == "notice") {
return BoaderType.notice;
} else if (value == "free") {
return BoaderType.free
}
return BoaderType.undefinde;
}
swift나 kotlin의 경우 string값을 enum으로 변환해주는 기능을 언어적으로 제공한다.
// swift
enum BoaderType: String {
case notice
case free
case undefinde
}
let boaderType = BoaderType(rawValue: "notice")
// kotlin
enum class BoardType(val code: String) {
NOTICE("notice")
FREE("free")
UNDEFINED("")
companion object {
fun getByCode(code: Int) = Color.values().find { it.code == code }
}
}
val boardType = BoardType.getByCode("notice")
하지만 dart에서는 위와 같이 언어적으로 enum으로 쉽게 변환할 수 있는 기능이 없어 직접 비교 구문을 사용해야 하는 불편함이 있다.
아래 코드는 비교 구분 없이 언어적으로 조금 더 깔끔하게 enum으로 변하고 값을 사용할 수 있도록 만든 코드이다.
Extension과 EnumData 클래스를 이용한 쉬운 enum변환 및 활용
Dart에서는 Extension을 이용해서 enum을 확장해서 사용할 수 있다.
EnumData라는 클래스를 만들어 enum에 필요한 property를 정의하였고, extension의 code와 name getter을 통해 별도의 조건식 없이 값을 가져다 사용할 수 있도록 하였다.
class EnumData {
final String code;
final String displayName;
EnumData({required this.code, required this.displayName});
}
enum BoardType { notice, free, undefined }
extension BoaderTypeExt on BoaderType {
static final _data = {
BoaderType.notice: EnumData(code: 'notice', displayName: 'Notice'),
BoaderType.free: EnumData(code: 'free', displayName: 'Free'),
BoaderType.undefined: EnumData(code: '', displayName ''),
};
static BoaderType.getByCode(String code) {
try {
return _data.entries.firstWhere((el) => el.value.code == code).key;
} catch (e) {
return BoaderType.undefined;
}
}
String get code => _data[this]!.code;
String get displayName => _data[this]!.displayName;
}
Dart 2.15에서는 name과 byName을 사용할 수 있다.
flutter 2.8부터 사용할수 있는 dart2.15에서 enum 기능이 조금 추가되었다.
다른 언어에서 처럼 name과 byName() 함수를 사용할 수 있다.
final boardType = BoardType.values.byName('notice') // BoardType.notice
print(boardType.name) // 'notice'
Dart 2.17에서 enum은 다르다!!!
flutter 3.0에서 사용되는 dart 2.17에서는 그동안 불편했던 enum에 많은 기능이 추가되었다.
enum에서도 일반 class처럼 property나 method, static method를 추가할 수 있게 되었다.
(이제는 enum의 기능 확장을 위해 별도의 extension을 정의할 필요가 없다. )
드디어 다른 언어들에서 처럼 좀 편하게 enum을 사용할 수 있을 것 같다.
dart 2.17 이후부터는 아래와 같이 extension도움 없이 enum을 편하게 사용해보자!
enum BoardType {
notice('notice', '공지사항'),
free('free', '자유게시판'),
undefined('undefined', '');
const BoardType(this.code, this.displayName);
final String code;
final String displayName;
factory BoardType.getByCode(String code){
return BoardType.values.firstWhere((value) => value.code == code,
orElse: () => BoardType.undefined);
}
}
마치며
로직 중간에 문자열을 직접 사용하는 코드를 만들어서는 안 됩니다.
특히 고정된 값 들만 있을 경우에는 꼭 enum으로 만들어서 사용하시기 바랍니다.
'Flutter' 카테고리의 다른 글
[Flutter] Multiple Flutter : FlutterEngine의 다양한 생성과 활용 (1) | 2022.07.13 |
---|---|
[Flutter] Freezed : 우리는 왜 immutable 객체를 사용해야 하는가? (0) | 2022.07.06 |
현업 개발자가 바라본 Flutter 3.0 Release (0) | 2022.05.14 |
[Flutter] Lint : 코딩컨벤션 (0) | 2022.01.11 |
[Flutter] Equatable : equals와 hashCode를 위한 라이브러리 (0) | 2021.12.27 |
- Total
- Today
- Yesterday
- DART
- Element LifeCycle
- enum member
- Route
- Flutter
- flutter l10n
- Flutter3.0
- RenderObject
- json_serializable
- flutter i18n
- flutter 다국어처리
- flutter2.0
- dart 2.17
- flutter_secure_storage
- dart enum
- freezed
- python3
- MVVM
- Mutiple Flutter
- flutter element
- navigator
- flutter mvvm
- FlutterEngine
- StatefulWidget LifeCycle
- widget element
- Android
- Widget Tree
- Flutter LifeCycle
- LocalKey
- Flutter TDD
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |