제네릭
- 자료형을 특정 문자로 지정해서 타입 매개변수와 타입 인자로 사용하는 것
- 함수나 클래스 등을 제네릭으로 사용하면 사용 시점에 다양한 자료형을 처리해서 사용할 수 있음.
타입 매개변수와 타입 인자를 지정하는 위치
- 타입 매개변수는
<>
괄호 안에 하나 이상 정의할 수 있음. 보통 대문자 T, R, P, U를 사용
- 함수, 확장함수, 확장속성은
fun
, val/var
다음에 <>
괄호를 사용하여 타입 매개변수 작성
- 클래스, 인터페이스, 추상 클래스는 이름 다음에
<>
괄호를 사용하여 타입 매개변수 작성
제네릭 함수
- 함수의 매개변수와 반환 타입을 일반 문자(T, R, P, U)로 지정해서 정의한 함수
- 함수가 호출될 때 해당 자료형을 인자로 지정하면 지정한 타입의 함수를 호출한 결과를 반환함.
fun main() {
println(add(1, 2) { x, y -> x + y })
println(add("1", "2") { x, y -> x + y })
}
fun <T> add(x: T, y: T, op: (T, T) -> T): T = op(x, y)
실행결과
3
12
타입 매개변수의 매개변수와 반환 자료형 분리
- 입력과 반환하는 결과가 다른 자료형일 경우 반환하는 자료형을 분리해서 타입 매개변수를 지정할 수 있음.
- 보통 반환 자료형의 타입 매개변수는 R로 표시함.
fun main() {
println(sum(1, 2) { x, y -> "${(x + y)}!!!"})
println(sum(1, 2) { x, y -> (x + y).toDouble()})
}
fun <T, R> sum(x: T, y: T, op:(T, T) -> R): R = op(x, y)
실행결과
3!!!
3.0
타입 매개변수에 특정 자료형을 제한하기
- 제네릭 함수의 타입 매개변수에 특정 자료형으로 처리하도록 제한할 수 있음.
- 지정된 자료형과 그 하위 자료형만 타입 인자로 처리할 수 있음.
- 복수개의 타입을 제한하려면
where
키워드를 붙이면 됨.
import java.lang.Appendable
fun main() {
sumA("2", "1") { x, y -> x + y } // 에러 숫자 타입만 처리 가능
sumA(2, 1) { x, y -> x + y } // ok
val name = StringBuilder("사랑하자!")
suffix(name)
println(name) // 사랑하자! 코틀린
}
fun <T: Number> sumA(x: T, y: T, action: (T, T) -> T): T = action(x, y)
fun <T> suffix(str: T) where T: CharSequence, T: Appendable {
str.append("코틀린")
}