Kotlin 기초 - 2. enum, when (Kotlin in Action)

Tnalxmsk·2024년 1월 1일

Kotlin

목록 보기
3/8

코틀린의 제어구조 - 선택 표현과 처리: enum과 when

when은 자바의 switch를 대치하되 훨씬 더 강력하며 자주 사용할 프로그래밍 요소

enum 클래스 정의

enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

enum은 소프트 키워드라 부르는 존재로, class 앞에 있을 때는 특별한 의미를 지니지만 다른 곳에서는 이름에 사용할 수 있다.

enum은 단순히 값만 열거하는 존재가 아니며 enum class 안에 프로퍼티나 메서드를 정의할 수 있다.

enum class Color(val r: Int, val g: Int, val b: Int) { // 상수의 프로퍼티를 정의
    RED(255, 0, 0), ORANGE(255, 165, 0), // 각 상수를 생성할 때 그에 대한 프로퍼티 값을 지정
    YELLOW(255, 255, 0), GREEN(0, 255, 0), BLUE(0, 0, 255),
    INDIGO(75, 0, 130), VIOLET(238, 130, 238); // 반드시 세미콜론을 사용
    
    fun rgb() = (r * 256 + g) * 256 + b  // enum 클래스 안에서 메서드를 정의
}

코틀린에서 유일하게 세미콜론이 필수인 부분으로, enum class 안에 메서드를 정의하는 경우 반드시 enum 상수 목록과 메서드 정의 사이에 세미콜론을 넣어야 한다.

when으로 enum class 다루기

코틀린에서 자바의 switch에 해당하는 구성 요소는 when이다. if와 마찬가지로 when도 값을 만들어내는 식이다. 따라서 식이 본문인 함수에 when을 바로 사용할 수 있다.

fun getMnemonic(color: Color) =
    when (color) {
        Color.RED -> "Richard"
        Color.ORANGE -> "Of"
        Color.YELLOW -> "York"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        Color.INDIGO -> "In"
        Color.VIOLET -> "Vain"
    }

color로 전달된 값과 같은 분기를 찾는다. 각 분기의 끝에 break를 넣지 않아도 된다. 대응하는 분기를 찾으면 그 분기를 실행한다. 한 분기 안에서 여러 값을 매치 패턴으로 사용할 수도 있다. 그럴 경우 값 사이를 콤마로 분리한다.

fun getWarmth(color: Color) =
    when (color) {
        Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
        Color.GREEN -> "neutral"
        Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
    }

상수 import org.example.kotlin.Color.*값음 임포트하면 더 간단하게 구현할 수 있다.


fun getWarmth(color: Color) =
    when (color) {
        RED, ORANGE, YELLOW -> "warm"
        GREEN -> "neutral"
        BLUE, INDIGO, VIOLET -> "cold"
    }

when과 임의의 객체를 함께 사용

코틀린의 when의 분기 조건은 자바 switch와 달리 임의의 객체를 허용한다.

fun mix(c1: Color, c2: Color) =
    when (toSet(c1, c2)) {
        setOf(RED, YELLOW) -> ORANGE
        setOf(YELLOW, BLUE) -> GREEN
        setOf(BLUE, VIOLET) -> INDIGO
        else -> throw Exception("Dirty color")
    }

두 색상을 조합하여 혼합 색상을 만드는 것을 구현하기 위해 집합 비교를 사용한다. setOf 라는 함수를 통해 순서에 상관 없이 대응하는 색상이 있으면 해당 분기를 실행한다. 모든 분기 식에서 만족하는 조건을 찾을 수 없다면 else 분기의 문장을 계산한다.

인자 없는 when 사용

위의 예시는 비효율적이다. 함수가 호출될 때마다 각 분기 조건에 있는 두 색과 같은지 비교하기 위해 여러 Set 인스턴스를 생성한다. 이러한 비효율성이 크게 문제되진 않지만 이 함수가 자주 호출된다면 불필요한 가비지 객체가 늘어나는 것을 방지하기 위해 코트를 고치는 편이 좋을 것이다. 코드는 어려워지지만 성능을 더 향상시키기 위해 어느 정도 비용을 감수해야하는 경우도 있다.

fun mixOptimized(c1: Color, c2: Color) =
    when {
        (c1 == RED && c2 == YELLOW) || (c1 == YELLOW && c2 == RED) -> ORANGE
        (c1 == BLUE && c2 == YELLOW) || (c1 == YELLOW && c2 == BLUE) -> GREEN
        (c1 == VIOLET && c2 == BLUE) || (c1 == BLUE && c2 == VIOLET) -> INDIGO
        else -> throw Exception("Dirty color")
    }

when에 아무 인자가 없으려면 각 조건이 불리언 결과를 계산하는 식이어야 한다. 위의 mix 함수와 같은 기능을 하지만 추가 객체를 만들지 않는다는 장점이 있으나 가독성이 떨어진다.

0개의 댓글