Page 24 -
P. 24

}

                   println(root.depth) // 2
                 }

               제네릭 클래스에서와 달리 프로퍼티나 함수를 제네릭으로 선언할 때는 타입 파라미터를 fun이나
               val/var 바로 뒤에 위치시킨다는 점에 유의하라.

               클래스 멤버 프로퍼티는 타입 파라미터를 가질 수 없고, 오직 확장 프로퍼티만 타입 파라미터를
               가질 수 있다. 일반 멤버 프로퍼티에 대한 타입 파라미터를 허용하지 않는 이유는 이런 프로퍼티
               를 사용할 때 지정한 타입 인자에 따라 여러 값을 제공하는 일이 불가능하기 때문이다. 일반 프로

               퍼티는 근본적으로 한 값만 제공한다.

                 // error: type parameter of a property must be used in its receiver type
                 var <T> root: TreeNode<T>? = null

               같은 이유로 객체 선언에 타입 파라미터를 추가하는 것도 금지된다.

                 object EmptyTree<T> // error: type parameters are not allowed for objects


               프로퍼티 참조는 타입 인자를 지원하지 않는다. 따라서 제네릭 프로퍼티의 타입 파라미터는 수신
               객체 타입으로부터 추론돼야 한다. 제네릭 (확장) 프로퍼티를 선언하면서 타입 파라미터를 사용하
               지 않는 경우에도 마찬가지 이유로 컴파일 시점 오류가 된다.


                 // error: expression 'depth' of type 'Int' cannot be invoked as a function.
                 val minDepth = TreeNode("").depth<String>

                 // error: type parameter of a property must be used in its receiver type
                 val <T> TreeNode<String>.upperCaseDataget() = data.toUpperCase()




               9.1.2 바운드와 제약


               기본적으로 타입 인자로 들어갈 수 있는 타입에는 아무런 제약이 없다. 따라서 타입 파라미터들은
               Any? 타입과 동의어인 것처럼 처리된다. 하지만 제네릭 클래스를 구현하면서 다뤄야 할 데이터의
               타입에 좀 더 많은 정보가 필요한 경우가 많다. TreeNode 예제를 확장해서 모든 트리 노드에 저장

               된 값들의 평균을 계산하는 함수를 선언하고 싶다고 하자. 이런 종류의 연산은 수를 저장한 트리




         364





     Kotlin_05.indd   364                                                                    2022-02-15   오후 4:08:04
   19   20   21   22   23   24   25   26   27   28   29