Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
inline 関数
Kotlinの『inline』関数は、呼び出し時にコンパイラが関数本体をそのまま展開(インライン化)します。ラムダを引数にとる高階関数に使うとオブジェクト生成のオーバーヘッドを削減でき、ラムダ内から外側の関数に『return』できるようになります。
構文
// inline 関数の定義
inline fun measure(block: () -> Unit) {
val start = System.currentTimeMillis()
block()
println("${System.currentTimeMillis() - start}ms")
}
// noinline — 特定のラムダをインライン化しない
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { ... }
// crossinline — インライン化しつつ non-local return を禁止
inline fun bar(crossinline block: () -> Unit) { ... }
// reified — インライン化により型情報を実行時に保持できます。
inline fun <reified T> isInstance(value: Any): Boolean = value is T
修飾子一覧
| 修飾子 | 概要 |
|---|---|
| inline | 関数本体を呼び出し箇所に展開します。ラムダのオブジェクト生成を削減します。 |
| noinline | inline 関数の特定のラムダ引数をインライン化しません。ラムダを変数に保存したいときに使います。 |
| crossinline | inline 化しつつも non-local return(ラムダから外側の関数に return)を禁止します。 |
| reified | inline 関数のみで使えます。型パラメーターを実行時に参照できるようにします。 |
サンプルコード
// 処理時間計測の inline 関数
inline fun measureTime(label: String, block: () -> Unit) {
val start = System.currentTimeMillis()
block()
println("$label: ${System.currentTimeMillis() - start}ms")
}
// reified で型情報を実行時に使います。
inline fun <reified T> filterByType(list: List<Any>): List<T> {
return list.filterIsInstance<T>()
}
// inline 関数ではラムダから外側の関数に return できます(non-local return)
inline fun findFirst(list: List<Int>, predicate: (Int) -> Boolean): Int? {
for (item in list) {
if (predicate(item)) return item // このラムダの return は findFirst を抜けます。
}
return null
}
fun main() {
// measureTime の使用
measureTime("処理") {
Thread.sleep(10)
println("処理中...")
}
// reified の使用(型情報を実行時に利用します)
val mixed: List<Any> = listOf(1, "hello", 2.5, "world", 42, true)
val strings = filterByType<String>(mixed)
val ints = filterByType<Int>(mixed)
println("文字列: $strings") // [hello, world]
println("整数: $ints") // [1, 42]
// non-local return(inline のため外側の main() から return できます)
val numbers = listOf(1, 3, 5, 7, 2, 9)
val firstEven = findFirst(numbers) { it % 2 == 0 }
println("最初の偶数: $firstEven") // 2
// 標準ライブラリの inline 関数の例
val result = listOf(1, 2, 3, 4, 5).let { list ->
list.filter { it > 2 }.sumOf { it }
}
println("3以上の合計: $result") // 12
}
概要
通常、Kotlinのラムダ式はコンパイル時にオブジェクトとして生成されます。『inline』を使うと呼び出し箇所にコードが展開されるため、ラムダのオブジェクト生成コストがなくなります。頻繁に呼ばれるユーティリティ関数に有効です。
『reified』型パラメーターは『inline』関数でのみ使えます。通常のジェネリクスは実行時に型消去されますが、『inline』化することで型情報を保持でき、『is T』や『T::class』が使えます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。