[Kotlin] 코틀린 기초(3) - when

sw·2021년 12월 26일
0

1. 사용법

  • when도 if문과 마찬가지로 값을 만들어내는 expression이므로 다음과 같이 쓸 수 있다.
    Java와 달리 분기의 끝에 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 getColor(color: Color) =
    when (color) {
        Color.RED -> "빨강"
        Color.GREEN -> "초록"
        Color.BLUE -> "파랑"
    }
  • 여러 값을 매치 패턴으로 사용할 경우, 값 사이에 콤마( , )로 구분한다.
fun getColor(color: Color) =
    when (color) {
        Color.RED, Color.GREEN-> "빨초"
        Color.BLUE -> "파랑"
    }
  • Kotlin when의 분기 조건은 임의의 객체를 허용한다.
fun getColor(c1: Color, c2: Color) =
    when (setOf(c1, c2)) {
        setOf(Color.RED, Color.BLUE) -> "PURPLE"
        setOf(Color.RED, Color.GREEN) -> "YELLOW"
        else -> "NOTHING"
    }
  • 인자 없는 when 사용
    위에 코드는 호출될 때마다 여러 set 인스턴스를 생성한다. 만약 이 함수가 자주 호출돼서 불필요한 가비지 객체가 늘어나는 것을 방지하기 위해 다음과 같이 사용하면 된다. 단, 가독성은 떨어진다.
fun mixOptimized(c1: Color, c2: Color) =
    when {
        (c1 == Color.RED && c2 == Color.BLUE) ||
                (c1 == Color.BLUE && c1 == Color.RED) -> "PURPLE"
        (c1 == Color.RED && c2 == Color.GREEN) ||
                (c1 == Color.GREEN && c1 == Color.RED) -> "YELLOW"
        else -> "NOTHING"
    }

2. 스마트 캐스트 (타입 검사 + 타입 캐스트)

  • 코틀린에서는 is를 사용해 변수 타입을 검사한다. (Java의 instanceof와 비슷하다)
    어떤 변수가 원하는 타입인지 일단 is로 검사하고 나면 굳이 변수를 원하는 타입으로 캐스팅하지 않아도 컴파일러가 대신 캐스팅을 해주기 때문에 바로 사용 가능하다. 이를 스마트 캐스트라고 한다.
interface Expr  
// 단지 여러 타입의 expression 객체를 아우르는 공통 타입 역할

class Num(val value: Int) : Expr
// value 라는 프로퍼티만 존재하는 단순한 클래스로 Expr 인터페이스를 구현한다.

class Sum(val left: Expr, val right: Expr) : Expr
// Expr 타입의 객체라면 어떤 것이나 Sum 연산의 인자가 될 수 있다.

fun eval(e: Expr): Int =
    when (e) {
        is Num -> e.value
        is Sum -> eval(e.left) + eval(e.right)
        else -> throw IllegalArgumentException("Unknown expression")
    }
  • 스마트 캐스트is로 변수에 든 값의 타입을 검사한 다음에 그 값이 바뀔 수 없는 경우에만 작동한다.
    ex) 클래스의 프로퍼티에 대해 스마트 캐스트를 사용한다면 그 프로퍼티는 반드시 val이어야 하고 커스텀 접근자를 사용한 것이어도 안된다. 해당 프로퍼티를 다른 클래스가 상속하면서 커스텀 접근자를 정의함으로써 스마트 캐스트의 요구 사항을 깰 수 있기 때문이다.

  • 원하는 타입으로 명시적으로 타입 캐스팅하려면 as 키워드를 사용한다.

	val name = e as Num
profile
끄적끄적

0개의 댓글