신규 블로그를 만들었습니다!

2020년 이후부터는 아래 블로그에서 활동합니다.

댓글로 질문 주셔도 확인하기 어려울 수 있습니다.

>> https://bluemiv.tistory.com/

코틀린에는 스마트 캐스트(Smart cast)가 있습니다.

 

간단하게 설명하면, 프로그래머가 굳이 원하는 타입으로 캐스팅 하지 않더라도, 컴파일러가 알아서 캐스팅해주는 것을 말합니다. 이해를 돕기 위해 천천히 예제를 살펴봅시다.

 

SumNum이라는 프로퍼티만 있는 class를 만들어봅시다. 코틀린의 클래스를 만드는 법을 모르시는 분은 아래 글을 참고하세요.

 

2019/02/07 - [Language/Kotlin] - 코틀린의 필드와 접근자(getter, setter) 사용방법

 

코틀린의 필드와 접근자(getter, setter) 사용방법

들어가기 앞서, 클래스에 대한 간단한 개념을 알아야하는데, 우리가 클래스를 사용할 때는... 내부의 데이터를 캡슐화(encapsulate)하고, 캡슐화한 데이터를 다루는 코드를 클래스라는 하나의 주체안에 가둬두기..

hongku.tistory.com

스마트 캐스트

간단하게 (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번째 줄을 보면 eNum을 가질때, 값을 그대로 반환 합니다. 6번째 줄을 보면 eSum일 때, 왼쪽과 오른쪽을 더한 값을 반환합니다.

 

이제 여기서 스마트 캐스트(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 사용방법

 

코틀린의 enum class 사용방법

enum class를 살펴보기전에 enum에 대한 개념을 간단하게 아는 것이 좋습니다. 만약 잘 알고 있는 분은 "여기"를 누르고 바로 코틀린의 enum class를 살펴보세요. JAVA의 enum 클래스 Java에서는 상수를 선언할때..

hongku.tistory.com

2019/02/11 - [Language/Kotlin] - 코틀린, enum class와 when 사용하기

 

코틀린, enum class와 when 사용하기

코틀린에는 when이라는 키워드가 있습니다. when은 Java에서 switch와 같은 역할을 합니다. 조금은 다른부분이 있지만, 거의 동일합니다. 글을 시작하기 앞서, enum class에 대해서 잘 모르시는 분은 아래 글을 읽..

hongku.tistory.com

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기