이넘 클래스란?
이넘 클래스는 미리 정의된 상수들로 이뤄진 제한된 집합을 표현하는 클래스다. 정수, 문자열 등과 비교할 때 이넘을 사용하면 어떤 값이 가능한 범위 안에 들어가 있는지를 일일이 검사할 필요가 없으므로, 정해진 상수들로 이뤄진 집합을 타입 안전하게 아룰 수 있다.
다음은 간단한 이넘 클래스의 예시이다.
enum class Result {
SUCCESS, ERROR
}
fun Result.isSuccess() = this == Result.SUCCESS
fun main() {
println(Result.SUCCESS.isSuccess()) // true
println(Result.ERROR.isSuccess()) // false
}
추가로 이넘은 내부 클래스나 함수 본문에서 정의할 수 없다.
다른 타입과 마찬가지로 when을 사용하면 이넘 변수를 각각의 값과 비교할 수 있다. 이 때 이넘을 사용할 때 when 식에서 모든 이넘 상수를 다룬 경우에는 else 가지를 생략 가능하다.
enum class Result {
SUCCESS, ERROR
}
fun changeResult(result: Result) = when(result) {
Result.SUCCESS -> Result.ERROR
Result.ERROR -> Result.SUCCESS
}
만약 빠뜨린 부분이 없는 when 식을 사용할 때, 새 이넘 값을 추가하는 경우를 생각해보자.
import java.lang.IllegalArgumentException
enum class Result {
SUCCESS, ERROR
}
fun changeResult(result: Result) = when(result) {
Result.SUCCESS -> Result.ERROR
Result.ERROR -> Result.SUCCESS
else -> throw IllegalArgumentException("Invalid result: $result")
}
새로운 이넘 값을 추가할 때까지는 위의 코드가 잘 작동한다. 하지만 새 값을 추가하면 예외를 발생시킨다. 만약 else를 사용하지 않는 when을 사용하면, 컴파일 시점에 changeResult() 함수의 when에 빠뜨린 부분이 있다고 경고하기 떄문에 이런 오류를 쉽게 방지할 수 있다.
커스텀 멤버가 있는 이넘
다른 클래스와 마찬가지로 이넘 클래스도 멤버를 포함할 수 있다. 그 외에도 원한다면, 이넘에도 확장 함수나 프로퍼티를 붙일 수 있다.
enum class Result {
SUCCESS, ERROR;
fun isSuccess() = this == Result.SUCCESS
}
fun main() {
println(Result.SUCCESS.isSuccess()) // true
println(Result.ERROR.isSuccess()) // false
}
이넘 클래스에 생성자가 있으면 각 이넘 상수의 정의 뒤에도 적절한 생성자 호출을 추가해야 한다.
enum class Result(val bol: Boolean) {
SUCCESS(true), ERROR(false);
val isSuccess get() = bol
}
fun main() {
println(Result.SUCCESS.isSuccess) // true
println(Result.ERROR.bol) // false
}
공통 멤버 사용하기
모든 이넘 값에는 ordinal과 name이라는 한 쌍의 프로퍼티가 들어있다. ordinal은 이넘 클래스 안에 정의된 이넘 값의 순서에 따른 인덱스이고, name은 이넘 값의 이름이다. 또한 특정 이넘 클래스의 값을 이넘 본문에 있는 정의의 위치에 따라 서로 비교할 수 있다.
enum class Result {
SUCCESS, ERROR;
}
fun main() {
println(Result.SUCCESS.name) // SUCCESS
println(Result.ERROR.ordinal) // 2
println(Result.SUCCESS == Result.ERROR) // false
println(Result.SUCCESS != Result.ERROR) // true
println(Result.SUCCESS < Result.ERROR) // true
println(Result.SUCCESS >= Result.ERROR) // false
}
valueOf() 메서드는 이넘 값의 이름을 문자열로 넘기면 그에 해당하는 이넘 값을 반환한다.
enum class Result {
SUCCESS, ERROR;
}
fun main() {
println(Result.valueOf("SUCCESS")) // SUCCESS
val result = enumValues<Result>()
println(result[1])
println(enumValueOf<Result>("ERROR")) // ERROR
}
'Android > Kotlin' 카테고리의 다른 글
[Kotlin Coroutine] (1) - 자바 동시성, 스레드 (0) | 2023.05.31 |
---|---|
Sealed Class (0) | 2023.05.26 |
Abstract Class & Interface (0) | 2023.05.25 |
변수 캡슐화하기 (Encapsulate Variable) (0) | 2023.05.12 |
REST API, Retrofit (0) | 2023.05.01 |