Generics Kotlin

기본응용
Number의 부분 클래스인 형식 T의 Generic

fun <T:Number> oneHalf(value:T):Double {
return value.toDouble()/2.0
}
fun main(args: Array<String>) {
println(oneHalf(3))
}

fun <T:Comparable<T>> max(first:T,second:T):T{
return if (first > second) first else second
}
fun main(args: Array<String>) {
println(max("kotlin","java")) // kotlin
}


여러 제약 설정하기

fun <T> ensureTrailingPeriod(seq: T) where T : CharSequence, T : Appendable {
if (!seq.endsWith('.')) {
seq.append('.')
}
}

fun main(args: Array<String>) {
val s = StringBuilder("Hello World")
ensureTrailingPeriod(s)
println(s)
}


class Processor<T> {
fun process(value: T) {
value?.hashCode()
}
}
널이 될 수 없는 형식으로 제한: Any

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

Generics 형식에 맞는 is 연산
: value가 List<*> 임의 형식인 경우: Star Projection
if (value is List<*>) {...}

제네릭형식으로 타입 캐스트하기

fun printSum(c: Collection<*>) {
val v = c as? List<Int> ?: throw IllegalArgumentException("List is expected")
println(v.sum())
}

fun main(args: Array<String>) {
printSum(listOf(1, 2, 3))
// printSum(setOf(1, 2, 3))
// printSum(listOf('a', 'b', 'c'))
}
warning: unchecked cast: Collection<*> to List<Int>
val v = c as? List<Int> ?: throw IllegalArgumentException("List is expected")

reified Generic (reified: 구체화된)

inline fun<T> isA(value: Any) = value is T
// inline fun <reified T> isA(value: Any) = value is T

fun main(args: Array<String>) {
println(isA<String>("abc"))
println(isA<String>(123))
val items = listOf("one", 2, "three")
println(items.filterIsInstance<String>())
}


reified 를 사용하지 않으면 에러 발생

error: cannot check for instance of erased type: T
inline fun<T> isA(value: Any) = value is T

reified로 지정하면 value의 형식이 T의 인스턴스인지를 실행시점에 검사할 수 있음
reified 가 되려면 inline함수여야 함
즉 지정하지 않으면 컴파일 시점에 T에 대한 형식이 지정되어 컴파일 됨

표준 라이브러리에는 filterIsInstance 함수가 있는데 이 함수가 내부적으로는 reified를 사용







덧글

댓글 입력 영역