아규먼트로 함수에 값을 전달할 수 있는것처럼 타입 아규먼트를 사용하면 함수에 타입을 전달할수 있다.
타입 아규먼트를 사용하는 함수를 제너릭 함수라고 부르며, 대표적인 예로는 filter 함수가 있다.
inline fun <T> Iterable<T>.filter() : List<T> {
val destination = ArrayList<T>
for (element in this){
if(predicate(element){
destination.add(element)
}
}
return destination
}
타입 파라미터는 컴파일러가 타입을 조금이라도 더 정확하게 추측할수 있게 해준다.
filter 함수에서 컴파일러가 아규먼트가 컬렉션 요소와 같은 타입이라는것을 알 수 있으므로, 잘못처리하는것을 막을수 있다.
타입 파라미터의 중요한 기능중 하나는 구체적인 타입의 서브타입만 사용하게 타입을 제한하는것이다.
fun <T: Comparble<T>> Iterable<T>.sorted(): List<T>{
}
fun <T, C : MutableCollction<in T>>
Iterble<T>.toCollection(destination : C) : C {
}
위의 예시처럼 서브타입으로 제한하면, T를 서브타입으로 제한하면, T를 기반으로 반복처리할수 있다.
또한 많이 사용하는 제한으로는, Any가 있는데 이는 nullable이 아닌 타입을 나타 낸다.
inline fun<T,R : Any> Iterable<T>.mapNotNull(
transform : (T) - > R?
){
return mapNotNullTo(ArrayList<R>(), transform)
}
드물지만 다음과 같이 둘 이상의 제한을 걸수도 있다.
fun <T: Aniaml> pet(animal: T) where T: GoodTempered {
}
//또는
fun <T> pet(animal: T) : Animal , T: GoodTemperd{
}
코틀린의 자료현 시스템에서 타입 파라미터는 굉장히 중요하다.
이를 활용하여 type-safe한 제네릭 알고리즘과 제너릭 객체를 구현한다.
타입 파라미터를 사용할때는 서브타입을 제한하여, 특정 자료형이 제공하는 메서드를 안전하게 사용이 가능하다.