코틀린

선택 표현과 처리

누룽지맛치킨 2023. 1. 25. 17:40

enum 클래스

enum class Color{
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}
  • enum 클래스 안에 프로퍼티나 메소드 정의 가능
enum class Color(val r: Int, val g: Int, val b: Int){
    RED(255,0,0), GREEN(0,255,0), BLUE(0,0,255);

    fun rgb() = (r * 256 + g) * 256 + b
}

fun main() {
    println(Color.BLUE.rgb())
}
  • 각 enum 상수를 정의할 때 그 상수에 해당하는 프로퍼티 값을 지정해야함
  • enum 클래스 안에 메소드를 정의하는 경우 반드시 enum 상수 목록과 메소드 정의 사이에 세미콜론을 넣어함

when으로 enum 클래스 사용

enum class Color(val r: Int, val g: Int, val b: Int){
    RED(255,0,0), GREEN(0,255,0), BLUE(0,0,255);

    fun rgb() = (r * 256 + g) * 256 + b
}

fun getMnemonic(color: Color) =
    when(color){
        Color.RED -> "Richard"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        else -> "None"
    }

fun main() {
    println(getMnemonic(Color.BLUE))
}
  • 자바와 다르게 각 분기의 끝에 break를 넣지 않아도 된다.
  • 한 분기 안에서 여러 값을 매치 패턴으로 사용 가능
    • 값 사이를 콤마로 분리
enum class Color(val r: Int, val g: Int, val b: Int){
    RED(255,0,0), GREEN(0,255,0), BLUE(0,0,255);

    fun rgb() = (r * 256 + g) * 256 + b
}

fun getWarmth(color : Color) = 
    when(color){
        Color.RED, Color.GREEN -> "warm"
        Color.BLUE -> "cool"
    }

fun main() {
    println(getWarmth(Color.GREEN))
}
  • 코틀린 when의 분기 조건은 임의의 객체를 허용
enum class Color{
    RED, GREEN, BLUE, YELLOW, VIOLET, ORANGE, INDIGO
}

fun mix(c1: Color, c2: Color) = 
    when(setOf(c1, c2)){
        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")
    }

fun main() {
  println(mix(Color.BLUE, Color.YELLOW))
}
  • 위의 함수는 임의 객체를 계속 생성하기 때문에 불필요한 가비지가 계속 생성된다.
  • 아래와 같이 고칠 수 있다.
enum class Color{
    RED, GREEN, BLUE, YELLOW, VIOLET, ORANGE, INDIGO
}

fun mixOptimized(c1: Color, c2: Color) =
    when{
        (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() {
  println(mixOptimized(Color.BLUE, Color.YELLOW))
}
  • 하지만, 가독성이 떨어지는 단점이 있다.

스마트 캐스트

  • 타입 검사와 타입 캐스트를 조합
  • 어떤 변수가 원하는 타입인지 일단 is로 검사
  • 처음부터 그 변수가 원하는 타입으로 선언된 것처럼 사용 가능
  • 스마트 캐스트는 is로 변수에 든 값의 타입을 검사한 후 그 값이 바뀔 수 없는 경우에만 작동
  • 명시적 타입 캐스팅
    • as 키워드 사용
  • 예시
    fun eval(e: Expr) : Int =
      when(e) {
          is Num -> e.value
          is Sum -> eval(e.right) + eval(e.left)
          else -> throw IllegalArgumentException("Unknow expression")    
      }

 

참조

KOTLIN IN ACTION