2.2 코틀린 기초 / 선택 표현과 처리: enum과 when
코틀린의 when 은 자바의 switch를 대치하되 훨씬 더 강력하고 자주사용한다.
2.3.1 enum 클래스 정의
enum class Color{
RED,ORANGE,YELLOW,GREEN,BLUE,
}
enum 은 단순 값만 열거하는 존재가 아니라 프로퍼티나 메서드를 정의할 수 있다.
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 main(args: Array<String>) {
println(Color.BLUE.rgb())
}
여기서 코틀린 중에서 유일하게 ; 를 사용하는 것을 볼 수 있다.
enum 클래스 안에 메서들르 정의하는 경우
반드시 enum 상수 목록과 메서드 정의 사이에 세미콜론을 넣어야한다.
2.3.2 when 으로 enum 클래스 다루기
enum class Color {
RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}
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.BLUE))
}
자바와 다르게 break 를 안 넣어도 된다.
한 분기 안에 여러 값을 매치 패턴으로 사용할 수 있다. 이런 경우 , 를 이용해주면 된다.
enum class Color {
RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}
fun getWarmth(color: Color) = when(color) {
Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
Color.GREEN -> "neutral"
Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
}
fun main(args: Array<String>) {
p
2.3.3 when과 임의의 객체를 함께 사용
상수만 사용할 수 있는 자바의 switch와 달리 코틀린의 when은 임의의 객체 모두를 허용한다.
fun mix(c1: Color, c2: Color) =
when (setOf(c1, c2)) {
setOf(RED, YELLOW) -> ORANGE
setOf(YELLOW, BLUE) -> GREEN
setOf(BLUE, VIOLET) -> INDIGO
else -> throw Exception("Dirty color")
}
fun main(args: Array<String>) {
println(mix(BLUE, YELLOW))
}
2.3.4 인자 없는 when 사용
인자가 없으면 코드 읽기가 어려워지지만 성능을 더 향상시킨다.
fun mixOptimized(c1: Color, c2: Color) =
when {
(c1 == RED && c2 == YELLOW) ||
(c1 == YELLOW && c2 == RED) ->
ORANGE
(c1 == YELLOW && c2 == BLUE) ||
(c1 == BLUE && c2 == YELLOW) ->
GREEN
(c1 == BLUE && c2 == VIOLET) ||
(c1 == VIOLET && c2 == BLUE) ->
INDIGO
else -> throw Exception("Dirty color")
}
fun main(args: Array<String>) {
println(mixOptimized(BLUE, YELLOW))
}
위의 코드에 when 에 아무 인자도 없다
=> Boolean 값으로 판단.
2.3.5 스마트 캐스트: 타입 검사와 타입 캐스트를 조합
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
fun eval(e: Expr): Int {
if (e is Num) {
val n = e as Num //1)
return n.value
}
if (e is Sum) {
return eval(e.right) + eval(e.left) //2)
}
throw IllegalArgumentException("Unknown expression")
}
fun main(args: Array<String>) {
println(eval(Sum(Sum(Num(1), Num(2)), Num(4))))
}
Sum 의 경우 좌우 인자에 대해서 left 와 right property로 저장한다.
Expr 인터페이스에는 두 가지 구현 클래스가 존재
따라서 식을 평가하려면 두 가지 경우를 고려해야한다.
- 어떤 식이 수라면 그 값을 반환한다
- 어떤 식이 합계라면 좌항과 우항의 값을 계산한 다음에 그 두 값을 합한 값을 반환한다.
1) 에서 Num으로 타입을 변환하는데 이는 불필요한 중복이다.
2)변수 e에 대해 스마트 캐스트를 사용한다.
- 코틀린에서는 is 를 이용하여 변수 타입을 검사한다.
- 원하는 타입으로 명시적으로 타입 캐스팅하려면 as 키워들르 사용한다.
스마트 캐스트는 값이 바뀔 수 없는 경우에만 작동!! => 해당 property에 대한 접근이 항상 같은 값을 내놓는다고 확인을 해야한다.
2.3.6 리팩토링: if를 when 으로 변경
fun eval(e: Expr): Int =
if (e is Num) {
e.value
} else if (e is Sum) {
eval(e.right) + eval(e.left)
} else {
throw IllegalArgumentException("Unknown expression")
}
fun main(args: Array<String>) {
println(eval(Sum(Num(1), Num(2))))
}
위의 코드를 when 을 이용해서 다듬어 보자.
fun eval(e: Expr): Int =
when (e) {
is Num -> //1)
e.value //2)
is Sum -> //1)
eval(e.right) + eval(e.left) //2)
else ->
throw IllegalArgumentException("Unknown expression")
}
fun main(args: Array<String>) {
println(eval(Sum(Num(1), Num(2))))
}
1) 인자 타입을 검사하는 when 분기들
2) 이부분에 스마트 캐스트가 쓰였다.
타입을 검사하고나면 스마트 캐스트가 이뤄진다
-> Num 이나 Sum의 멤버에 접근할 때 변수를 강제로 캐스팅할 필요가 없다.
2.3.7 if와 when 의 분기에서 블록 사용
fun evalWithLogging(e: Expr): Int =
when (e) {
is Num -> {
println("num: ${e.value}")
e.value //1)
}
is Sum -> {
val left = evalWithLogging(e.left)
val right = evalWithLogging(e.right)
println("sum: $left + $right")
left + right //2)
}
else -> throw IllegalArgumentException("Unknown expression")
}
fun main(args: Array<String>) {
println(evalWithLogging(Sum(Sum(Num(1), Num(2)), Num(4))))
}
1) 이 식이 블록의 마지막 식이므로 e의 타입이 Num 이면 e.value를 반환
2) e의 타입이 Sum 이면 이 식의 값이 반환된다.
Author And Source
이 문제에 관하여(2.2 코틀린 기초 / 선택 표현과 처리: enum과 when), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jacob31/2.2-코틀린-기초-선택-표현과-처리-enum과-when저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)