[Kotlin] Enum

강승구·2023년 3월 11일
0

Enum

enum 클래스는 미리 정의된 상수들로 이뤄진 제한된 집합을 표한하는 특별한 클래스이다.

아래 예시는 enum class의 가장 단순한 형태로 본문에 상수를 모아둔 형태이다.

enum class WeekDay {
    MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

fun WeekDay.isWork() = 
	this==WeekDay.SATURDAY || this==WeekDay.SUNDAY

fun main(){
    println(WeekDay.MONDAY.isWork()) //FALSE
    println(WeekDay.SATURDAY.isWork()) //TRUE
}

정수, 문자열 등과 비교할 때 enum을 사용하면 어떤 값이 가능한 범위 안에 들어가 있는지를 일일히 검사할 필요가 없으므로, 정해진 상수들로 이뤄진 집합을 type-safe하게 다룰 수 있다.
이때 컴파일러는 enum 타입의 변수가 enum class에 정의된 값 중 하나를 사용하는지 검사해준다.

코틀린 enum은 enum class라는 두 키워드의 조합으로 정의되지만, 자바는 enum으로 정의된다.

enum에서 사용되는 상수들은 컴파일 시점 상수이므로 보통 대문자를 사용한다.

enum은 특히 특정 타입에 속하는 미리 정해진 전역상수를 정의한다는 점에서 객체 정의와도 비슷하다.
객체와 마찬가지로 전역 상수를 사용할 수 있는 방법이 없는 위치에서는 enum을 정의할 수 없다.
예를 들어 enum을 inner class나 함수 본문에서 정의할 수 없다.

fun main(){
    enum class Direction {
        NORTH, SOUTH, WEST, EAST // ERROR
    }
}

Enum과 when

다른 타입의 값과 마찬가지로 when을 사용하면 enum 변수를 각각의 값과 비교할 수 있다.
하지만 enum을 사용하면 한가지 장점이 더 있다. when 식에서 모든 enum 상수를 다룬 경우에는 else문을 생략할 수 있다.

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

fun rotateClockWise(direction: Direction) = 
    when(direction){
        Direction.NORTH -> Direction.EAST
        Direction.SOUTH -> Direction.NORTH
        Direction.WEST -> Direction.SOUTH
        Direction.EAST -> Direction.WEST         
    }

내부적으로 빠진 부분이 없는 when 식에는 NoWhenBranchMatchedException 타입의 예외를 던지는 else 문이 암시적으로 추가된다.
또한 인텔리J IDE에서는 불필요한 else문이 추가되었다면 이를 제거할 것을 제안하기도한다.


커스텀 멤버가 있는 enum 정의

다른 클래스와 마찬가지로 enum class도 멤버를 포함할 수 있다. 그 외에도 확장 함수나 프로퍼티를 추가하는 것도 가능하다.

enum class WeekDay {
    MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    
    val lowerCaseName get() = name.lowercase()
    fun isWork() = this==WeekDay.SATURDAY || this==WeekDay.SUNDAY
}


fun main(){
    println(WeekDay.MONDAY.isWork())
    println(WeekDay.SATURDAY.lowerCaseName)
}

enum class에 생성자가 있다면 각 enum 상수의 정의 뒤에도 적절한 생성자 호출을 추가해야한다.

enum class Rainbow(val isCold: Boolean){
    RED(false), ORANGE(false), YELLOW(false),
    GREEN(false), BLUE(false), INDIGO(false), VIOLET(true)
}

Enum class의 공통 멤버

코틀린의 모든 enum class는 암시적으로 kotlin.Enum 클래스의 하위 타입이다. kotlin.Enum 클래스는 모든 enum 클래스가 사용할 수 있는 공통 함수와 프로퍼티를 제공한다. 몇가지 API 차이를 제외하면 이런 공통 멤벝들은 자바의 java.lang.Enum에 이쓴ㄴ 상응하는 멤버들과 비슷한다.

모든 enum 값에는 ordinal과 name이라는 한 쌍의 프로퍼티가 포함되어 있다. ordinal은 enum class 안에 정의된 enum 값의 순서에 따른 index이고 name은 enum 값의 이름이다.

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

fun main(){
	println(Direction.WEST.name) // WEST
    println(Direction.WEST.ordinal) // 3
}
profile
강승구

0개의 댓글