1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Kotlin】crossinline の役割と使いどころ

Posted at

1. 背景:インライン関数と非ローカルリターン

Kotlin の inline 関数は 高階関数のオーバーヘッドを削減 できるだけでなく、
ラムダ内で 非ローカルリターン(外側の関数から return)を可能にします。

例:非ローカルリターン

inline fun forEach(list: List<Int>, action: (Int) -> Unit) {
    for (item in list) action(item)
}

fun main() {
    val numbers = listOf(1, 2, 3, 4)
    forEach(numbers) {
        if (it == 3) return   // ✅ main() からリターン
        println(it)
    }
    println("End") // 実行されない
}

便利ですが、「意図しない return」が外側に伝播してしまう危険があります。


2. crossinline とは?

crossinline を付けると、

  • ラムダはインライン化される(オーバーヘッドなし)
  • 非ローカルリターンは禁止(ラムダ内では return できない)

という制約が課されます。


3. crossinline の例

inline fun runTask(crossinline action: () -> Unit) {
    val runnable = Runnable {
        action()  // インライン化されるが非ローカルリターンは不可
    }
    runnable.run()
}

fun main() {
    runTask {
        println("Start")
        // return   // ❌ コンパイルエラー(非ローカルリターン禁止)
        println("End")
    }
}

Runnable やコールバックに渡すケースでは、非ローカルリターンがあると設計上危険
そこで crossinline を付けて安全にする。


4. crossinline を使う場面

  1. コールバックや非同期処理
    • ラムダを別スレッドで実行する場合、外側関数への return は不自然なので禁止する。
    • 例:Runnable, Thread, Async API などに渡すラムダ
  2. 関数オブジェクトに変換して保持する場合
    • ラムダをクロージャに包んで保持する時、非ローカルリターンがあると制御フローが破壊されるため禁止。
  3. 安全な設計を強制したい場合
    • inline を活かしてオーバーヘッドを減らしつつ、return による外側終了は避けたいときに使う。

5. まとめ表

修飾子 インライン化 非ローカルリターン 関数オブジェクト化
inline ✅ される ✅ 許可 ❌ 不可
noinline ❌ されない ❌ 禁止 ✅ 可
crossinline ✅ される ❌ 禁止 ❌ 不可

まとめ

  • inline のラムダは非ローカルリターン可能だが、予期せぬ制御フローを生む危険がある
  • crossinline を付けると インライン化はされるが、非ローカルリターンは禁止
  • 主な使いどころは コールバック・非同期処理・Runnable などに渡すラムダ
  • inline / noinline / crossinline を組み合わせることで柔軟かつ安全に設計できる

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?