신규 블로그를 만들었습니다!
코틀린에는 when이라는 키워드가 있습니다. when은 Java에서 switch와 같은 역할을 합니다. 조금은 다른부분이 있지만, 거의 동일합니다.
글을 시작하기 앞서, enum class에 대해서 잘 모르시는 분은 아래 글을 읽고 오시면 이해하기 쉽습니다.
2019/02/10 - [Language/Kotlin] - 코틀린의 enum class 사용방법
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) 사용방법
2019/02/10 - [Language/Kotlin] - 코틀린의 enum class 사용방법
2019/02/09 - [Algorithm/백준 온라인 저지] - 백준 15905번 UCPC는 무엇의 약자일까? 코틀린으로 풀기
'Language > Kotlin' 카테고리의 다른 글
코틀린의 이터레이션 for, while 루프 (0) | 2019.02.13 |
---|---|
코틀린의 is와 스마트 캐스트(Smart cast)란? (2) | 2019.02.12 |
코틀린의 enum class 사용방법 (0) | 2019.02.10 |
코틀린의 필드와 접근자(getter, setter) 사용방법 (0) | 2019.02.07 |
코틀린의 문자열 템플릿(Kotlin String Templates) (0) | 2019.02.06 |
최근댓글