1. クロージャとは?
クロージャ (Closure) とは、
- 関数の外部にある変数をキャプチャ(保持)し、その状態にアクセスできる関数 のことです。
Kotlin では ラムダ式 や 無名関数 がクロージャの役割を果たせます。
ポイント
- 外部スコープの変数を参照・変更できる
- 関数のライフサイクルを超えて変数の状態を保持できる
2. 基本例
fun makeCounter(): () -> Int {
var count = 0
return { ++count } // 外部変数 count をキャプチャ
}
fun main() {
val counter = makeCounter()
println(counter()) // 1
println(counter()) // 2
println(counter()) // 3
}
解説
-
countはmakeCounter関数のローカル変数 - 通常なら
makeCounterが終了すると破棄される - しかし、返したラムダが
countをキャプチャしているため、呼び出しのたびに値が保持される
3. ラムダとクロージャ
ラムダ式は外部の変数にアクセスできます。
var greeting = "Hello"
val sayHello = { name: String -> "$greeting, $name" }
println(sayHello("Anna")) // Hello, Anna
greeting = "Hi"
println(sayHello("Anna")) // Hi, Anna
外部変数 greeting がクロージャに取り込まれており、値が変化すればラムダの挙動も変わります。
4. 無名関数とクロージャ
無名関数でも同じようにクロージャが利用可能です。
fun multiplier(factor: Int): (Int) -> Int {
return fun(x: Int): Int {
return x * factor // 外部変数 factor をキャプチャ
}
}
val times3 = multiplier(3)
println(times3(5)) // 15
5. クロージャの利用例
(1) 状態を持つ関数
- カウンター、累積値の計算、イベントの発火回数の追跡など
(2) コールバック処理
- 関数の外で定義した値を使ってコールバックを動作させる
(3) 関数型プログラミング
-
map/filter/reduceなどの高階関数で外部スコープの変数を参照
var threshold = 3
val numbers = listOf(1, 2, 3, 4, 5)
val filtered = numbers.filter { it > threshold }
println(filtered) // [4, 5]
まとめ
- クロージャ = 外部スコープの変数をキャプチャして保持する関数
- ラムダ や 無名関数 がクロージャを実現できる
- 外部変数の状態に依存する処理をシンプルに書ける
- 状態保持・コールバック・高階関数でよく利用される