[Effective Kotlin] 아이템 22. 일반적인 알고리즘을 구현할 때 제네릭을 사용하라

Jimin Lim·2023년 8월 4일
0

Effective Kotlin

목록 보기
22/39
post-thumbnail

아이템 22

일반적인 알고리즘을 구현할 때 제네릭을 사용하라

제네릭 예시

타입 아규먼트를 사용해 함수에 타입을 전달할 수 있다.
다음은 stdlib의 filter 함수의 예시다.

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
}

타입 파라미터가 컴파일러에게 타입 정보를 전달해, 컴파일 시점에 타입을 알 수 있다.

제네릭 제한

타입 파라미터의 중요한 기능 중 하나는 구체적인 타입의 서브타입만 사용하게 타입을 제한하는 것이다.

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> (/* ... */) { /*...*/ }

: 뒤에 슈퍼타입을 설정해 제한을 걸고 있다. Comparable<T>로 제한한다면 해당 타입을 비교한다는 것을 알 수 있다.

많이 사용하는 제한으로는 Any가 있으며, nullable이 아닌 타입을 나타낸다.

inline fun <T, R: Any> Iterable<T>.mapNotNull(
    transform: (T) -> R?
): List<R> {
    return mapNotNullTo(ArrayList<R>(), transform)
}

둘 이상의 제한을 걸 때는 다음과 같이 where을 사용해 작성할 수 있다.

fun <T> pet(animal: T) where T: Animal, T: GoodTempered {
}
profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

0개의 댓글