본문 바로가기

코틀린

코틀린(Kotlin) - when과 스마트 캐스트

이번에는, 코틀린의 구성요소 중 when과 스마트 캐스트에 대해 설명하고자 합니다.

 

when은 자바의 switch문을 대치하되, 훨씬 더 강력하며, 앞으로 자주 사용하게 될 프로그래밍 요소라고 생각합니다.

일반적인 when문

fun getNumber(value: Int) {
  when (value) {
    1 -> println("One")
    2 -> println("Two")
    3 -> println("Three")
  }
}

getNumber(1)
>> One

값을 리턴하는 when문

when은 코틀린에서 if와 마찬가지로, 값을 만들어내는 "식"의 기능을 할 수 있습니다.

따라서, 식이 본문인 함수에 when을 바로 사용하여 값을 리턴 할 수 있습니다.

단, 주의할 점은 when이 리턴값을 가지는 "식"의 기능으로 사용하게 되면, 반드시 모든 경우의 조건을 정의해줘야 합니다.

 

fun getNumber(value: Int) =
  when (value) {
    1 -> "One"
    2 -> "Two"
    3 -> "Three"
    else -> "else" //예외 케이스 정의 
  }
  
println(getNumber(1))
>> One

 

자바의 switch문과 비교한다면, "case"는 "->" 로 표현하고, "default"는 "else"로 표현합니다.

또한, 자바와 달리 각 분기의 끝에 break를 넣지 않아도 됩니다! (간혹 break를 빼먹어서 원치 않은 결과가 나오는 경우를 경험해보셨을 수도 있습니다...)

when 분기 안에, 여러 값 사용하기

when은 한 분기(case) 안에서 여러 값을 매치 패턴으로 사용할 수도 있습니다. 이런 경우에는 값 사이를 콤마(,)로 구분합니다.

 

when (value) {
  2, 4, 6, 8, 10 -> println("짝수")
  1, 3, 5, 7, 9 -> println("홀수")
}

다양한 조건식을 가지는 when문

when문은 표현식, 범위(range)를 조건식으로 가질 수도 있습니다.

 

val obj = Person("안드로이드", 10)

when (obj) {
  is Person -> println("True") //코틀린에서는 is를 사용해 객체 타입을 검사합니다. (자바의 instanceof와 비슷)
  else -> println("False")
}

>> True

 

val score = 90

when (score) {
  in 90..100 -> println("A")
  in 80 until 90 -> println("B")
  in 70 until 80 -> println("C")
  else -> println("F")
}

>> A

인자 없는 when문

when에 아무 인자도 없이 분기에 조건문을 바로 사용할 수 있으며, 이 경우에는 반드시! 각 분기의 조건이 Boolean 결과를 계산하는 식이여야 합니다.

(분기에 들어갈 추가적인 객체를 만들지 않는다는 장점이 있지만, 가독성은 좀 떨어지는 것 같습니다...!)

 

//when에 아무 인자도 없다.
when {
  (score >= 90) -> println("A")
  (80 <= score || score < 90) -> println("B")
  (70 <= score || score < 80) -> println("C")
  else -> println("F")
}

 


스마트 캐스트 : 타입 검사와 타입 캐스트 수행

코틀린에서는 "is"를 사용해 변수 타입을 검사합니다.

is 검사는, 자바의 instanceof와 비슷하다고 할 수 있는데, 자바에서는 instanceof로 타입을 확인한 후, 그 타입에 속한 멤버에 명시적으로 변수 타입을 캐스팅해줘야 합니다.

반면에, 코틀린에서는 프로그래머 대신 컴파일러가 캐스팅을 해줍니다. (짱!)

어떤 변수가 원하는 타입인지 일단 is로 검사하고 나면, 굳이 변수를 원하는 타입으로 캐스팅해주지 않아도, 마치 처음부터 그 변수가 해당 타입으로 선언된 것처럼 사용할 수 있습니다.

이를 스마트 캐스트라고 합니다.

 

//Person
class Person(val name:String, var age:Int)

//Car
class Car(val manufacturer: String, val model: String)

//스마트 캐스트
when (obj) {
  is Person -> println(obj.name) //Person으로 인식되어, Person의 변수 접근 가능
  is Car -> println(obj.manufacturer) //Car로 인식되어, Car의 변수 접근 가능
}

 

이렇게, 코틀린 컴파일러가 타입을 해석해주기 때문에, 명시적 캐스팅 없이 자동으로 형 변환이 이루어져, 바로 사용할 수가 있습니다.

 

만약, 타입이 바뀔 수 있는 경우의 변수라면, "as"키워드를 사용하여 원하는 타입으로 명시적 캐스팅이 가능합니다.

 

val person = obj as Person

 

지금까지, 자바의 switch와 비슷한 코틀린의 when에 대해 알아보았고, 코틀린 컴파일러가 자동으로 타입 검사와 타입 변환을 해주는 스마트 캐스트에 대해 알아보았습니다.

 

이제 제법, 코드들이 코틀린다운 코드로 점점 발전해가고 있는 것 같습니다. ^^