신규 블로그를 만들었습니다!
코틀린에는 스마트 캐스트(Smart cast)가 있습니다.
간단하게 설명하면, 프로그래머가 굳이 원하는 타입으로 캐스팅 하지 않더라도, 컴파일러가 알아서 캐스팅해주는 것을 말합니다. 이해를 돕기 위해 천천히 예제를 살펴봅시다.
Sum
과 Num
이라는 프로퍼티만 있는 class
를 만들어봅시다. 코틀린의 클래스를 만드는 법을 모르시는 분은 아래 글을 참고하세요.
2019/02/07 - [Language/Kotlin] - 코틀린의 필드와 접근자(getter, setter) 사용방법
스마트 캐스트
간단하게 (1 + 2) + 4를 수행하는 기능을 만들 예정입니다. 그러기 위해서 Num, Sum을 생성합니다.
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
Num
은 입력받은 값을 반환하고, Sum
은 왼쪽(left), 오른쪽(right)와 같이 2개를 받아 더한 뒤에 그 값을 반환합니다.
위의 코드는 아직 값을 반환하는 역할은 하고 있지 않습니다. 그런 역할을 하기 위해 eval
이란 메소드를 생성합니다.
fun eval(e: Expr): Int{
if (e is Num){
val n = e as Num // 불필요한 타입 변환
return n.value
}
if (e is Sum){
return eval(e.left) + eval(e.right) // 변수 e에 대한 스마트 캐스트
}
throw IllegalArgumentException("Unknown expression")
}
실행 결과
7
위와같이 eval
이란 메소드를 만들었습니다.
2번째 줄을 보면 e
가 Num
을 가질때, 값을 그대로 반환 합니다. 6번째 줄을 보면 e
가 Sum
일 때, 왼쪽과 오른쪽을 더한 값을 반환합니다.
이제 여기서 스마트 캐스트(Smart Cast
) 기능이 나옵니다. 3번째 줄을 보면 e as Num
이 있는데 e라는 인터페이스를 Num으로 타입 캐스팅을 하고 있습니다. 사실 코틀린에서는 위와 같은 상황에서는 캐스팅을 해줄 필요가 없습니다. is
라는 키워드는 검사를 한뒤에 자동으로 캐스팅까지 해주기 때문입니다. (이 부분을 스마트 캐스트라고 함) 그렇기 때문에 코드 3번째 줄은 무의미한 코드가 됩니다.
한편, 7번째 줄을 살펴보면 e is Sum
으로 인해, e
는 이미 Sum
으로 스마트 캐스팅 되었습니다.
정리하자면, 코틀린에서는 is
로 검사한 뒤 프로그래머 대신 컴파일러가 캐스팅을 해줍니다. 그렇기 때문에, is
로 검사하고 나면 굳이 원하는 변수로 캐스팅 할 필요가 없습니다.
스마트 캐스팅이 됐는지 확인 하는방법으로 IDE
를 이용하는 방법이 있습니다. 인텔리제이를 사용하시는 분이라면, e
에 색상이 입혀져 있는 것을 확인 할 수 있습니다. (아래 그림 참조)
위의 예제를 좀 더 코틀린 답게 수정해보도록 합시다.
if문을 이용해서, 코틀린 답게 코드 짜기
fun eval2(e: Expr): Int =
if (e is Num) {
e.value
} else if (e is Sum) {
eval2(e.left) + eval2(e.right)
} else {
throw java.lang.IllegalArgumentException("Unknown expression")
}
fun main(arg: Array<String>){
println(eval2(Sum(Sum(Num(3), Num(3)), Num(4))))
}
if문 식을 이용해서 코드를 짤 수 있습니다. 앞에서 살펴봤듯이 is를 통해 검사와 캐스팅 모두 해주기 때문에, 따로 타입 캐스팅을 할 필요 없습니다.
만약, Num도 아니고 Sum도 아닐 경우는 Error를 발생합니다.
if문 말고 when
으로도 코드를 리펙토링 해봅시다.
실행 결과
10
When을 이용해서 코틀린 답게 코드 짜기
fun eval3(e: Expr): Int =
when(e) {
is Num -> e.value
is Sum -> eval3(e.left) + eval3(e.right)
else -> throw IllegalArgumentException("Unknown expression")
}
fun main(arg: Array<String>){
println(eval3(Sum(Sum(Num(10), Num(7)), Num(3))))
}
when을 이용할때도 똑같습니다. is를 통해 검사와 캐스팅을 동시에 합니다.
실행결과
20
본 글은 Dmitry Jemerov, Svetlana Isakova의 "Kotlin in action" 책을 참고하여 작성한 글입니다.
다른 글
2019/02/10 - [Language/Kotlin] - 코틀린의 enum class 사용방법
2019/02/11 - [Language/Kotlin] - 코틀린, enum class와 when 사용하기
'Language > Kotlin' 카테고리의 다른 글
코틀린 맵(map) 이터레이터 (0) | 2019.02.14 |
---|---|
코틀린의 이터레이션 for, while 루프 (0) | 2019.02.13 |
코틀린, enum class와 when 사용하기 (0) | 2019.02.11 |
코틀린의 enum class 사용방법 (0) | 2019.02.10 |
코틀린의 필드와 접근자(getter, setter) 사용방법 (0) | 2019.02.07 |
최근댓글