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