Page 30 -
P. 30

자바에서는 캐스트를 활용하거나 리플렉션(reflection)을 통해 타입 소거를 우회해야 한다. 두 방식
               모두 단점이 있다. 캐스트는 문제를 (컴파일이 되도록) 덮어버려서 나중에 오류가 발생한다. 반대
               로 리플렉션 API를 사용하면 성능에 영향을 미칠 수 있다. 코틀린은 이 두 가지 약점을 모두 극복

               할 수 있는 세 번째 해법을 제공한다.
               구체화는 타입 파라미터 정보를 런타임까지 유지한다는 뜻이다. 어떻게 컴파일러가 타입 소거를
               우회할 수 있을까? 해답은 인라인한 함수에 대해서만 구체화한 타입 파라미터를 쓸 수 있다는 데

               있다. 함수 본문을 호출 위치로 인라인시키기 때문에 컴파일러가 인라인된 함수에 제공되는 타입
               인자의 실제 타입을 항상 알 수 있다.

               파라미터를 구체화하려면 reified 키워드로 해당 타입 파라미터를 지정해야 한다. 이 기능을 활
               용해 isInstanceOf() 함수를 고쳐보자. 인라인 함수는 재귀 함수일 수 없으므로 먼저 구현을 약간
               수정해야 한다.


                 fun <T>TreeNode<T>.cancellableWalkDepthFirst(
                   onEach: (T) -> Boolean
                 ): Boolean {
                   // 자바 LinkedList는 Deque를 구현하고 있어서 스택으로도 사용 가능함
                   // 자바 Stack 사용은 권장하지 않음
                   val nodes = java.util.LinkedList<TreeNode<T>>()

                   nodes.push(this)

                   while (nodes.isNotEmpty()) {
                     val node = nodes.pop()
                     if (!onEach(node.data)) return false
                       node.children.forEach { nodes.push(it) }
                   }

                   return true
                 }

                 inline fun <reified T> TreeNode<*>.isInstanceOf() =
                   cancellableWalkDepthFirst{ it is T }


               이 코드는 별도의 cancellableWalkDepthFirst()라는 인라인되지 않는 함수로 트리 순회 로직을
               추출해 사용한다. 예를 들어 이 함수를 다음과 같이 호출할 수 있다.







         370





     Kotlin_05.indd   370                                                                    2022-02-15   오후 4:08:04
   25   26   27   28   29   30   31   32   33