Hanbit the Developer
Kotlin Documentation | Inline functions 본문
Category: Concepts - Functions
문서 링크: https://kotlinlang.org/docs/inline-functions.html
higher-order function는 객체이며 메모리를 추가로 할당하고 virtual call을 발생시키기 때문에 오버헤드가 발생한다.
아래 코드를
lock(l) { foo() }
아래로 치환하게 되면 이러한 오버헤드가 줄어들게 된다. 함수 객체를 파라미터로 받는 대신 컴파일러가 아래의 코드를 생성한 것이다.
l.lock()
try {
foo()
} finally {
l.unlock()
}
이는 아래와 같이 inline 키워드를 추가함으로써 적용할 수 있다.
inline fun <T> lock(lock: Lock, body: () -> T): T { ... }
noinline
inline 함수에서 특정 함수를 inline 취급하고 싶지 않다면 해당 함수 앞에 noinline을 붙이면 된다.
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { ... }
Non-local returns
inline function에서 바깥 함수에서의 반환을 유도할 수 있다. 람다에 위치해있지만 람다를 감싸고 있는 함수에서 탈출하는 것을 non-local returns라고 부른다.
fun foo() {
ordinaryFunction {
return // ERROR: cannot make `foo` return here
}
}
fun foo() {
inlined {
return // OK: the lambda is inlined
}
}
crossinline
전달된 inline function이 내부에서 직접 실행되는 것이 아니라 다른 컨택스트에서 실행되는 경우, non-local control flow가 허용되지 않는다. 해당 inline function이 non-local returns가 불가능하다는 것을 명시하기 위해, crossinline을 사용한다.
inline fun f(crossinline body: () -> Unit) {
val f = object: Runnable {
override fun run() = body()
}
// ...
}
*다른 컨택스트에서 사용함에도 불구하고 crossinline을 명시하지 않으면 컴파일 에러가 발생한다.
Reified type parameters
인자로 전달된 타입에 접근하기 위해, reified를 사용한다.(대안: reflection)
inline fun <reified T> TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p.parent
}
return p as T?
}
Inline properties
val foo: Foo
inline get() = Foo()
var bar: Bar
get() = ...
inline set(v) { ... }
프로퍼티 전체에 inline을 마킹하는 경우 get(), set() 모두에 inline을 적용하게 된다.
inline var bar: Bar
get() = ...
set(v) { ... }
'Kotlin' 카테고리의 다른 글
Kotlin Documentation | Collections overview (0) | 2023.05.24 |
---|---|
Kotlin Documentation | Operator overloading (0) | 2023.05.23 |
Kotlin Documentation | Lamdas (0) | 2023.05.23 |
Kotlin Documentation | Functions (0) | 2023.05.23 |
Kotlin Documentation | Type aliases (0) | 2023.05.23 |