[TIL] Kotlin - 일반적인 알고리즘을 구현할 때 제네릭을 사용하라.
Effective kotlin - Item 22
일반적인 알고리즘을 구현할 때 제네릭을 사용하라.
제네릭의 이점
inline fun <T> Iterable<T>.filter(
predicate: (T) -> Boolean
): List<T> {
val destination = ArrayList<T>()
for (element in this) {
if(predicate(element)) {
destination.add(element)
}
}
return destination
}
- 위 예제는 타입 파라미터 T를 갖는 제네릭 함수
- 타입 파라미터는 컴파일러에 타입과 관련된 정보를 제공하여 컴파일러가 타입을 더 정확하게 추측할 수 있도록 도와줍니다.
- IDE가 이를 기반으로 유용한 제안을 한다.
- T의 타입이 T타입임을 강제
제네릭 제한
fun <T: Comparable<T>> Iterable<T>.sorted(): List<T> {
...
}
fun <T, C: MutableCollection<in T>>
Iterable<T>.toCollection(destination: C): C {
...
}
class ListAdapter<T: ItemAdapter>(...) { ...}
- 구체적인 타입의 서브타입만 사용하도록 타입을 제한하는것이 가능하다.
- 즉, 특정 Class의 Sub Class만 사용하도록
- 타입에 제한을 걸음으로써 내부에서 해당 타입이 제공하는 메서드를 사용할 수 있다.
제한으로 Any를 많이 사용한다
inline fun <T, : Any> Iterable<T>.mapNotNull(
trasnform: (T) -> R?
): List<R> {
return mapNotNullTo(ArrayList<R>(), transform)
}
- Any로 타입을 제한한 경우 이는
nullable
이 아님을 나타냅니다.
정리
- 제네릭은 타입 제한을 통해 특정 자료형이 제공하는 메서드를 안전하게 사용할 수 있다.