Kotlin으로 프로그래밍하면서 inline, crossinline, noinline 키워드를 본적은 있지만 자세히 다뤄보지 못하였다. 이번에 이들을 정리하고 언제 사용하는지 알고자 한다.
코틀린에서 inline, crossinline, noinline 키워드는 **고차 함수(higher-order function)**에서 사용됩니다.
inline 키워드는 고차 함수의 인자로 전달된 람다 함수를 호출하는 대신, 해당 람다 함수의 내용을 호출하는 함수의 코드에 직접 삽입합니다. 이를 통해 람다 함수의 호출 오버헤드를 줄일 수 있습니다.
inline 함수의 대표적인 예는 let, also, apply이다.
다음은 inline 키워드를 사용한 예시입니다.
inline fun processString(str: String, block: (String) -> Unit) {
println("Processing $str")
block(str)
}
fun main() {
processString("Hello, World!") { string ->
println(string.toLowerCase())
}
}
위 코드에서 processString
함수는 inline으로 선언되어있으며, block
인자로 전달된 람다 함수의 내용이 processString
함수의 코드에 직접 삽입됩니다.
하지만, inline 함수는 코드의 크기가 커지고, 함수 호출 횟수가 늘어나면 컴파일러가 최적화를 수행하지 못할 수 있습니다. 따라서, inline 함수는 함수의 크기와 호출 횟수가 적을 때 사용하는 것이 좋습니다.
crossinline 키워드는 inline으로 선언된 함수 내부에서 람다 함수를 호출하는 과정에서, 람다 함수 내부에서 return을 사용하지 못하도록 합니다.
고차함수가 nonlocal return을 허용하지 않아야 한다는 것을 의미한다. 바로 소비되지 않고 한번 더 전달된다는 느낌이다.
다음은 crossinline 키워드를 사용한 예시입니다.
inline fun processString(str: String, crossinline block: (String) -> Unit) {
println("Processing $str")
run {
block(str)
}
}
fun main() {
processString("Hello, World!") { string ->
if (string.isNotEmpty()) {
println(string.toLowerCase())
}
}
}
위 코드에서 processString
함수는 crossinline으로 선언되어있으며, block
인자로 전달된 람다 함수 내부에서 return을 사용할 수 없습니다.
crossinline 키워드를 사용하는 이유는, inline 함수의 특성상 람다 함수 내부에서 return을 사용하면 해당 람다 함수를 호출한 inline 함수의 코드에서도 return이 발생할 수 있기 때문입니다. 이러한 문제를 방지하기 위해, crossinline 키워드를 사용하여 람다 함수 내부에서 return을 사용하지 못하도록 합니다.