728x90
반응형
1. 리시버가 붙은 함수 리터럴
함수 리터럴에 리시버를 적용하여 확장 함수처럼 만들 수 있다.
리시버가 붙은 함수 리터럴에는 리시버를 나타내는 this 키워드를 사용할 수 있다.
호출은 리시버.변수(인수) 형태로 호출한다.
일반 함수 타입으로 호출할 때는 리시버를 첫 번째 인수로 전달하면 된다.
Int.(Int, Int) -> Int 타입은 (Int, Int, Int) -> Int 타입에 대입
fun main() {
// Int 리시버를 [left, right] 범위 이내로 가공하여 반환하는 확장 함수
// Int.(left: Int, right: Int) 리시버 타입이 Int, 매개변수의 타입이 (Int, Int)이며, 반환타입이 Int인 함수
val makeSure: Int.(left: Int, right: Int) -> Int
// 리시버가 적용된 함수 리터럴
// * 익명 함수 형태는 fun Int.(left: Int, right: Int): Int {...}로 적으면 된다.
makeSure = { left: Int, right: Int ->
if (this < left) left
else if (this > right) right
else this
} // makeSure
println(15.makeSure(20, 40))
println(18.makeSure(0, 50))
println(25.makeSure(0, 19))
}
2. 제네릭(Generic)
제네릭이라는 문법을 이용하면, 인수를 전달하듯이 함수에 타입을 전달할 수 있다.
fun <T> toFunction(value: T): () -> T = {value}
fun main() {
// toFunction(1107) 이렇게만 적어도 1107로 Int인 것을 추론할 수 있어 사용 가능
val func: () -> Int = toFunction<Int>(1107)
println(func())
}
fun 키워드와 함수 이름 사이의 <식별자> 부분을 타입 매개변수라고 부른다.
여기서는 식별자를 T로 했으므로, T 라는 이름의 타입 매개변수가 만들어진다.
이제 T를 하나의 타입처럼 사용할 수 있다.
위의 예제에서는 T 타입의 인수를 받아서 그 값을 그대로 돌려주는 함수를 반환하는 함수 선언했다.
제네릭이 적용된 함수를 호출하려면 함수 이름 옆에 <타입이름>을 적는다.
여기서 타입 이름 부분을 타입 인수라고 부른다.
3. 여러 타입을 인수로 받기
타입 인수를 여러 개 받으려면 fun 키워드와 함수 이름 사이를 <타입1, 타입2, ...> 형식으로 적는다.
// 타입 매개변수 T와 R을 선언하여, 두 개의 타입 인수를 받을 수 있음
// mapper 매개변수에는 T 타입을 R 타입으로 변환하는 함수를 받도록 함
// T.map처럼 확장 함수의 리시버에도 타입 매개변수를 적용할 수 있다.
fun<T, R> T.map(mapper: (T) -> R): R {
// 매개변수로 받은 mapper 함수에 리시버(this)를 넣어 호출한 뒤, 반환 값을 그대로 반환
return mapper(this)
}
fun main() {
// 11에 map 확장 함수 호출한 뒤 반환하는 함수를 mapper 매개변수로 전달. T와 R에 들어감
// map 확장 함수의 반환 값을 square 뱐수에 저장
val square: Int =
11.map {
it * it
}
println(square) // 121
}
4. 구체화된 타입 매개변수
다음 코드는 오류를 일으킨다. - 타입 매개변수는 is 연산자의 피연산자로 사용할 수 없다.
fun <T> check() {
val number = 0
if(number is T)
println("T는 Int 타입 입니다.")
}
타입 매개변수를 is 연산자의 피연산자로 사용하고 싶으면 다음과 같이 해야한다.
inline fun <reified T> check() {
val number = 0
if(number is T)
println("T는 Int 타입 입니다.")
}
fun main() {
check<Int>()
}
타입 매개변수 앞에 reified을 붙여주면 해당 타입 매개변수를 in 연산자에 사용할 수 있다.
타입 매개변수에 reified를 붙이려면 함수를 반드시 inline으로 선언해야 한다.
728x90
반응형
'TIL > Kotlin' 카테고리의 다른 글
[TIL/Kotlin] 코틀린 고급문법_in/out 키워드와 ..연산자와 범위 표현식 (0) | 2023.05.26 |
---|---|
[TIL/Kotlin] 코틀린 고급문법_클래스와 인터페이스에서 제네릭 사용하기, 제네릭이 적용된 인터페이스/클래스 상속·구현하기, 특정 타입을 상속·구현하는 타입만 인수로 받기 (0) | 2023.05.26 |
[TIL/Kotlin] 코틀린 고급문법_함수 참조, 고차 함수, 클로저(Closure) (0) | 2023.05.24 |
[TIL/Kotlin] 코틀린 고급문법_함수 리터럴과 람다식, 익명 함수, it 식별자 (0) | 2023.05.24 |
[TIL/Kotlin] 코틀린 고급문법_데이터 클래스와 객체 분해하기 (0) | 2023.05.21 |