Kotlin 제네릭(Generic)

제네릭 클래스

인수 Any 형으로 받아 Any 형의 속성에 저장함으로써, Int, Char, String 등 다양한 유형에 따라 클래스나 함수를 정의 할 수 있`다.

class Foo(val value: Any)

fun main() {
    val a1 = Foo(123)
    println(a1.value)		// 123
}

그러나 value는 Any 형이므로, 아래와 같이 value+ 1 연산을 하게 되면 오류가 발생한다.

class Foo(val value: Any)

fun main() {
    val a1 = Foo(123)
    println(a1.value + 1)	// Error
}

<T>으로 제네릭 형식을 정의함으로써 value는 Int, Char, String 등 인수에 따른 형식의 속성으로 취급하게 하여 이 문제를 해결 할 수 있다.

class Foo<T>(val value: T)

fun main() {
    val a1 = Foo(123)
    println(a1.value + 1)	// 124
}

아래와 같이하여 형식에 제한을 걸 수 있다. 아래에서는 IntDouble 등 Number의 서브 클래스로 제한하고 있다.

class Foo<T: Number>(val value: T)

제네릭 함수

함수에서도 제네릭을 사용할 수 있다. 다음은 임의의 타입 T의 인수를 받아, T형의 값을 반환하는 함수이다.

fun <T> foo(x: T): T { ... }

호출시 형식을 지정하지만 인수에 의해 형태가 명확한 경우는 생략 할 수 있다.

foo<Int>(123)
foo<String>("ABC")
foo(123)
foo("ABC")

아래와 같이하여 형식에 제한을 걸 수 있다. 아래에서는 IntDoubleNumber의 서브 클래스로 제한하고 있다.

fun <T: Number> foo(x: T): T { ... }

제약 조건을 여러 개 지정하려면 where를 사용한다.

fun <T> foo(x: T) where T: Runnable, T: Cancellable { ... }