1. インライン関数とは?
Kotlin では高階関数を使うと、関数オブジェクトが生成されて呼び出しコストが発生します。
インライン関数 (inline function) は、このオーバーヘッドを減らすために 関数呼び出しを呼び出し元に展開(インライン化) します。
特に ラムダを引数に取る高階関数 で使われます。
2. 基本構文
inline fun repeatAction(times: Int, action: () -> Unit) {
for (i in 1..times) {
action()
}
}
fun main() {
repeatAction(3) { println("Hello") }
}
解説
-
inline修飾子を付けると、関数呼び出しが展開される - 関数オブジェクトの生成が省略され、パフォーマンスが向上する
3. インライン化のメリット
-
パフォーマンス改善
- ラムダを引数に持つ関数の呼び出しオーバーヘッドを削減
-
非ローカルリターンが可能
- ラムダの中から外側の関数に
returnできる(通常のラムダでは不可)
- ラムダの中から外側の関数に
4. 非ローカルリターン
inline fun forEach(list: List<Int>, action: (Int) -> Unit) {
for (item in list) {
action(item)
}
}
fun main() {
val nums = listOf(1, 2, 3, 4)
forEach(nums) {
if (it == 3) return // 非ローカルリターン(main を抜ける)
println(it)
}
println("End") // 実行されない
}
通常のラムダでは「そのラムダ内」でしか return できないが、inline を付けると外側の関数からもリターンできる。
5. noinline 修飾子
引数の一部だけをインライン化したくない場合は noinline を付けます。
inline fun doSomething(
block1: () -> Unit,
noinline block2: () -> Unit
) {
block1()
block2() // インライン化されない
}
6. crossinline 修飾子
インライン化したラムダの中で 非ローカルリターンを禁止 したいときは crossinline を使います。
inline fun runAction(crossinline action: () -> Unit) {
val wrapper = Runnable { action() }
wrapper.run()
}
crossinline を付けると return は「そのラムダ内」に限定される。
まとめ
- インライン関数 = 呼び出しコードを展開して高階関数のオーバーヘッドを削減
- メリット: パフォーマンス改善、非ローカルリターンが可能
-
noinline: インライン化を抑制 -
crossinline: 非ローカルリターンを禁止