-
Kotlin) inline 함수와 고차함수 알아보기Kotlin 2020. 12. 15. 12:45
고차함수(Higher order fuctions)
- 인자가 함수이거나 함수를 리턴하는 함수
- 코틀린에서 고차함수를 사용하면 추가적인 메모리 할당 및 함수호출로 Runtime overhead가 발생합니다.
fun someMethod(a: Int, func: () -> Unit): Int { func() return 2 * a } fun main(args: Array<String>) { var result = someMethod(2) { println("Just some dummy fuction") } println(result) }
inline 개념
- inline fuctions는 내부적으로 함수 내용을 호출되는 위치에 복사하며, 고차함수의 Runtime overhead를 줄여줍니다.
- 컴파일하는 동안 해당 함수의 모든 사용 부분이 본문으로 바뀌게 됩니다.
- non-local return을 허용합니다.(caller function return 허용) -> return 값이 없이 return만 허용하는 것입니다.
inline fun repeat(times: Int, action: (Int) -> Unit) { for (index in 0 until times) { action(index) } } repeat(10) { print(it) } // 컴파일 시 for (index in 0 until 10) { print(index) }
- 타입 인자의 구체화가 가능합니다.
val any: Any = listOf<Any>() if (any is List<Int>) { /* Error */ } if (any is List<*>) { /* Ok */ }
- inline은 재귀일 수 없습니다 -> 무한대로 호출됨, 런타임 에러 발생
inline fun a() { b() } inline fun b() { c() } inline fun c() { a() }
crossinline과 noinline
crossinline
- inline 함수이지만, non-local return을 허용하지 않습니다.(caller fuction return 허용하지 않음)
fun main() { repeat(10) { print(it) return // ERROR: Not allowed } }
noinline
- 모든 인자를 inline으로 처리하고 싶지 않을 때, 인자 앞에 noinline 키워드를 사용하면 그 인자는 inline 키워드에서 제외됩니다.
- 인자를 다른 함수의 인자로 전달할 수 있습니다.
- inline 되지 않은 다른 함수의 인수로 사용하는 경우 사용됩니다.
inline fun newMethod(a: Int, func: () -> Unit, noinline func2: () -> Unit) { func() someMethod(10, func2) }
Reified 키워드를 사용하자
- inline에서만 사용할 수 있는 reified 키워드가 있습니다.
- Generics 타입 T 앞에 써주면 됩니다.
- reified를 사용하면 리턴 타입이 다른 함수를 오버로딩 할 수 있습니다.
inline fun <reified T> getMsg(number: Int): T { return when (T::class) { String::class -> "The number is : $number" as T Int::class -> number as T else -> "Neither String and Int" as T } }
위의 코드는 타입에 따라 리턴되는 타입이 다르도록 구현되어 있습니다. 아래와 같이 사용할 수 있습니다.
val result: Int = getMsg(10) println("result :$result") val resultString: String = getMsg(100) println("result :$resultString")
리턴되는 타입에 따라서 T가 결정되며 T에 따라서 리턴되는 객체가 달라집니다.
Summary
inline 함수를 주로 사용하는 경우는 다음과 같습니다.
- 매우 자주 사용되는 함수 -> pirnt 함수
- 구체화된 타입으로 된 타입 인수가 필요한 함수
- 컬렉션 처리 함수 -> map, filter, flatMap, joinToString
- 범위 함수 -> apply, let
- top-level 유틸리티 함수 -> repeat, run ,with
- 명확하지 않은 의미를 지닌 타입, 다른 측정 단위를 가질 수 있는 타입
- inline 함수로 API를 정의하는 경우는 거의 없습니다.
Reference
반응형'Kotlin' 카테고리의 다른 글
Kotlin) 코틀린 inner 클래스 알아보기 (0) 2020.12.18 Kotlin) 코틀린 infix 키워드 알아보기 (0) 2020.12.15 Kotlin) 코틀린 Collection - List, Map, Set 사용법 (0) 2020.12.15 Kotlin) 코틀린 ::class.java와 리플렉션(Reflection) (0) 2020.12.14 Kotlin) 코틀린 안드로이드 익스텐션 폐기 - Android Kotlin Extensions Will be removed in a future (0) 2020.12.08