신규 블로그를 만들었습니다!

2020년 이후부터는 아래 블로그에서 활동합니다.

댓글로 질문 주셔도 확인하기 어려울 수 있습니다.

>> https://bluemiv.tistory.com/

코틀린에는 when이라는 키워드가 있습니다. when은 Java에서 switch와 같은 역할을 합니다. 조금은 다른부분이 있지만, 거의 동일합니다.

 

글을 시작하기 앞서, enum class에 대해서 잘 모르시는 분은 아래 글을 읽고 오시면 이해하기 쉽습니다.

2019/02/10 - [Language/Kotlin] - 코틀린의 enum class 사용방법

 

코틀린의 enum class 사용방법

enum class를 살펴보기전에 enum에 대한 개념을 간단하게 아는 것이 좋습니다. 만약 잘 알고 있는 분은 "여기"를 누르고 바로 코틀린의 enum class를 살펴보세요. JAVA의 enum 클래스 Java에서는 상수를 선언할때..

hongku.tistory.com

 

 

 

 

Enum class와 when 사용하기

Java에서는 분기 조건에 상수(enum, Integer 리터럴)만을 사용할 수 있지만, Kotlin에서는 임의의 객체를 사용할 수 있도록 허용합니다.

 

그럼 예를 들어서 한번 살펴봅시다. enum class에서 정의한 특정한 색상에 대해 하나의 문자열을 대칭 시키고 싶을때, when을 사용하면 편합니다.

 

// 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
}

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"
}

fun main(args: Array<String>){
    println(getMnemonic(Color.RED))
}​

 

9번째 줄과 같이 when은 함수 뒤에 바로 = 를 이용하여 사용할 수 있습니다. 그리고, 자바에서는 switch문을 사용할 때 break를 입력을 해야하지만, 코틀린에서는 break를 넣지 않아도 됩니다.

 

위 예제는 Color에 대한 분기를 찾아, 색상에 해당하는 문자열을 가져옵니다. 그래서, 위 코드를 실행하면 아래와 같은 결과가 나옵니다.

 

실행 결과

Richard

 

하나의 분기에서 여러값 처리하기

만약 여러개의 색상에 대해서 같은 분기를 타게 하고 싶을때는 쉼표(,)를 이용하면 됩니다. 예를들어서 코드를 살펴봅시다.

 

// 여러개의 값을 하나의 분기에 표현할 때는 쉼표(,)를 이용
fun getMnemonic2 (color: Color) = when(color) {
    Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
    Color.GREEN -> "neutral"
    Color.BLUE, Color.INDIGO, Color.VIOLET -> "cool"
}
fun main(args: Array<String>){
    println(getMnemonic2(Color.BLUE))
}​

 

RED, ORANGE, YELLOW에 대해서 "warm"이란 문자열로 표현하고 싶을때, 위와 같이 쉼표(,)를 이용하면 됩니다.

 

실행 결과

cool

 

when 분기조건에 여러개 넣기

Kotlin에서 when의 좋은 점은 분기조건에 상수(enum, 숫자 리터럴) 뿐 아니라 임의의 객체를 허용하는 부분입니다. 이런 특징과 setOf() 메소드를 이용해서, 분기조건에 여러개를 넣을 수도 있습니다.

 

아래 예제를 살펴봅시다. (색상 2개를 입력받아 그 2개 색상 조합에 대해 알려주는 예제입니다.)

 

// setOf()를 이용해서, 분기 조건에 여러개의 값을 넣을 수 있다.
fun getMnemonic3 (color: Color, color2: Color) = when(setOf(color, color2)) {
    setOf(Color.RED, Color.YELLOW) -> Color.ORANGE
    setOf(Color.YELLOW, Color.BLUE) -> Color.GREEN
    setOf(Color.BLUE, Color.VIOLET) -> Color.INDIGO
    else -> throw Exception("Dirty Color") // 그 밖의 색상에 대해서는 Error
}
// Main
fun main(args: Array<String>){
    println(getMnemonic3(Color.RED, Color.YELLOW))
    println(getMnemonic3(Color.BLUE, Color.VIOLET))
    println(getMnemonic3(Color.VIOLET, Color.BLUE))
    println(getMnemonic3(Color.RED, Color.BLUE))
}
​

 

실행 결과

ORANGE

INDIGO

INDIGO

Exception in thread "main" java.lang.Exception: Dirty Color

at exam02.EnumClassWhenKt.getMnemonic3(EnumClassWhen.kt:24)

at exam02.EnumClassWhenKt.main(EnumClassWhen.kt:35)

 

setOf() 메소드는 여러 객체를 집합으로 즉, set객체로 만들어주는 메소드입니다. 그렇기 때문에, 집합(set)의 특성상 순서는 중요하지 않아서 11번째와 12번째 줄과 같이, 2개의 순서가 바뀌더라도 결과는 똑같이 나옵니다.

 

13번째 줄을 보면.. 없는 색상 조합을 넣을경우 Error를 일으킵니다.

 

when은 차례대로 위에서부터 아래로 조건과 동일한지 비교를합니다. (동등성, equility) 그리고 맞는 조건을 찾지 못하면, else 분기문을 실행합니다. (when을 사용하면 Java의 switch문보다 간결하고 아름답게 작성이 가능합니다.)

 

인자가 없는 when

하지만, 위 경우는 비교를 하면서 set 인스턴스를 계속 생성하기 때문에, 비효율적인 코드일 수도 있습니다. 인자가 없는 when을 사용하면 효율적인 코드를 만들 수 있습니다.

위와 같은 기능을 하는 코드를 인자가 없는 when으로 다시 만들어보면 아래와 같습니다.

 

fun mixOptimized(c1: Color, c2: Color) =
        when { // when의 분기조건이 없다.
            // 분기 조건이 없으려면, Boolean 결과를 계산하는 식이어야 함
            (c1 == Color.RED && c2 == Color.YELLOW) || (c1 == Color.YELLOW && c2 == Color.RED) -> Color.ORANGE
            (c1 == Color.YELLOW && c2 == Color.BLUE) || (c1 == Color.BLUE && c2 == Color.YELLOW) -> Color.GREEN
            (c1 == Color.BLUE && c2 == Color.VIOLET) || (c1 == Color.VIOLET && c2 == Color.BLUE) -> Color.INDIGO
            else -> throw Exception("Dirty Color")
        }
fun main(args: Array<String>){
    println(mixOptimized(Color.RED, Color.YELLOW))
    println(mixOptimized(Color.BLUE, Color.VIOLET))
    println(mixOptimized(Color.VIOLET, Color.BLUE))
    println(mixOptimized(Color.RED, Color.BLUE))
}
​

 

2번째 줄을 보면 when에 분지 조건이 없는것을 확인 할 수 있습니다. 하지만 분기 조건이 없으려면, 밑에 계산하는 식이 Boolean 결과를 계산하는 식이어야 합니다.

 

해당 코드는 위의 코드보다 가독성이 떨어지지만, 효율적인 측면에서는 더 높다고 할 수 있습니다.

 

본 글은 Dmitry Jemerov, Svetlana Isakova의 "Kotlin in action" 책을 참고하여 작성한 글입니다.

 

다른 글

2019/02/07 - [Language/Kotlin] - 코틀린의 필드와 접근자(getter, setter) 사용방법

 

코틀린의 필드와 접근자(getter, setter) 사용방법

들어가기 앞서, 클래스에 대한 간단한 개념을 알아야하는데, 우리가 클래스를 사용할 때는... 내부의 데이터를 캡슐화(encapsulate)하고, 캡슐화한 데이터를 다루는 코드를 클래스라는 하나의 주체안에 가둬두기..

hongku.tistory.com

2019/02/10 - [Language/Kotlin] - 코틀린의 enum class 사용방법

 

코틀린의 enum class 사용방법

enum class를 살펴보기전에 enum에 대한 개념을 간단하게 아는 것이 좋습니다. 만약 잘 알고 있는 분은 "여기"를 누르고 바로 코틀린의 enum class를 살펴보세요. JAVA의 enum 클래스 Java에서는 상수를 선언할때..

hongku.tistory.com

2019/02/09 - [Algorithm/백준 온라인 저지] - 백준 15905번 UCPC는 무엇의 약자일까? 코틀린으로 풀기

 

백준 15905번 UCPC는 무엇의 약자일까? 코틀린으로 풀기

해당 문제는 직접 풀어보고 채점까지 마친 뒤, 작성한 글입니다. 문제풀이는 아래쪽에 있으니, 풀이를 보고싶은 분은 아래쪽을 확인하시면 됩니다. 문제 출처 https://www.acmicpc.net/problem/15904 문제 UCPC는..

hongku.tistory.com

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기