오늘도 더 나은 코드를 작성하였습니까?

타입 파라미터의 제약 본문

Kotlin in Action/코틀린 답게 사용하기

타입 파라미터의 제약

hik14 2021. 3. 2. 10:59

타입 파라미터 제약

- 클래스나 함수에 사용할 수 있는 타입인자를 제한하는 기능

 

예를 들어 List<Int> List<Double>에 원소의 합을 구하는 sum 함수를 생각해 보자. List<String>같은 경우는 적용을 할 수가 없다.

이런 경우 sum 함수는 타입 파라미터로 숫자 타입만을 허용해야된다.

 

상한(upper bound)

- 제네릭 타입을 인스턴스화할 때 사용하는 타입 인자는 반드시 그 상한타입 이거나 그 상한타입의 하위타입이여야 한다.

fun <T : Number> List<T>.sum(): T{
    
}

 

타입 파라미터 T에 대한 상한을 정하고 나면 T타입의 값을 그상한 타입의 값으로 취급할 수 있다

fun <T : Number> oneHalf(value: T): Double{
    return value.toDouble() / 2.0   
} 

 

타입 파라미터를 제약하는 함수 선언하기

fun <T: Comparable<T>> max(first: T, second: T): T{
    return if( first > second) first else second
}

fun main() {
    println(max("kotlin", "java"))
    
}

T의 상한 타입은 Comparable<T> 이다. String 은 Comparable을 확장하기 때문에 max함수에 적합한 인자이다.

 

타입파라미터에 여러 제약을 가하기.

 

fun <T> ensureTrailingPeriod(seq: T)
    where T : CharSequence, T: Appendable{ // 파라미터 제약 목록.
        if (!seq.endsWith('.')){
            seq.append("!")
        }
    }

fun main() {
    val str = StringBuilder("Hello World")
    ensureTrailingPeriod(str)
    print(str)
}

위 코드는 CharSequence , Appendable 두 개의 인터페이스를 반드시 구현해야 한다는 사실을 표현한다.

데이터 접근 연산 endsWith, 데이터 변환 연산 append를  T 타입의 값에게 수행할 수 있다는 뜻이다.

 

타입 파라미터를 널이 될수 없는 타입으로 한정

널이 될 수 있는 타입을 포함되는 타입으로 타입인자를 지정해도 타입 파라미터를 만들 수 있다.

아무런 상한을 정하지 않은 타입 파라미터는 결과적으로 Any?를 상한으로 정한것과 같다.

class Processor<T>{
    fun process(value: T){
        value?.hashCode()
    }
}

fun main() {
    val nullableStringProcessor = Processor<String?>()
    nullableStringProcessor.process(null)
}

항상 널이 될 수 없는 타입마 타입인자로 받기 위해서는 제약을 가해야 된다. 널 가능성을 제외한 다른 제약이 필요없다면 Any를 상한으로 한다.

타입 파라미터를 널이 될 수 없는 타입으로 제약하기만 하면 타입 인자로 널이 될 수 있는 타입이 들어오는 것을 막을 수가 있다.

예를 들면 다른 널이 될 수 없는 타입이면 된다.  Comparable<T>

 

'Kotlin in Action > 코틀린 답게 사용하기' 카테고리의 다른 글

변성: 제네릭과 하위 타입  (0) 2021.03.02
실행시 제네릭스의 동작  (0) 2021.03.02
제네릭스  (0) 2021.02.26
고차 함수 안에서 흐름 제어  (0) 2021.02.26
컬렉션 연산 inline  (0) 2021.02.25