inline
한정자가 붙어 있다.
inline fun repeat(times: Int, action: (Int) -> Unit) {
for (index in 0 until times) { action(index) }
}
inline
한정자는 ‘함수를 호출하는 부분’을 ‘함수 본문’으로 대체하며 다음 장점이 있다.
repeat(10) { print(it) }
// 컴파일 후
for (index in 0 until times) {
print(index)
}
fun <T> printTypeName() {
print(T::class.simpleName) // 오류
}
reified
한정자를 지정하면 이 제한을 무시할 수 있다.
reified
한정자로 타입 파라미터를 사용한 부분이 타입 아규먼트로 대체된다.inline fun <reified T> printTypeName() {
print(T::class.simpleName)
}
// 사용
printTypeName<Int>() // Int
printTypeName<Char>() // Char
printTypeName<String>() // String
inline
한정자를 붙이면 조금 더 빠르게 동작한다.
() → Unit
는 Function0<Unit>
로 컴파일var l = 1L
noinlineRepeat(100_000_000) {
l += it
}
// 인라인이 아닌 람다에선 지역 변수 l을 직접 사용할 수 없어
// 컴파일 중 아래와 같이 레퍼런스 객체로 래핑되고
// 람다 표현식 내부에선 이를 사용한다.
val a = Ref.LongRef()
a.element = 1L
noinlineRepeat(100_000_000) {
a.element = a.element + it
}
return
을 사용할 수 없다.
return
으로 main
에 돌아올 수 없는 것fun main() {
repeatNoinline(10) {
print(it)
return // 오류
}
}
return
이 가능하다.fun main() {
repeat(10) {
print(it)
return // OK
}
}
inline
한정자는 유용하지만 모든 곳에 사용할 수는 없다.inline
한정자는 재귀적으로 사용할 수 없다.
inline fun a() { b() }
inline fun b() { c() }
inline fun c() { a() }
public
인라인 함수 내부에서 private
과 internal
가시성을 가진 함수와 프로퍼티를 사용하지 못한다.
internal inline fun read() {
var reader = Reader() // 오류
// ...
}
private class Reader {
// ...
}
inline
으로 받고 싶지 않을 때 유용한 한정자가 있다.
corssinline
noinline
inline fun requestNewToken(
hasToken: Boolean,
crossinline onRefresh: () -> Unit,
noinline onGenerate: () -> Unit,
) { /* ... */ }