笔友城堡 - 可定义的个人主页

前言

简单记录一下Kotlin中的闭包,Java中没这个概念,记录一下,方便自己查阅和学习。

正文

闭包

什么事闭包?

闭包 = 一个函数 + 它能访问的外部变量环境
//或者
把“自由变量”绑定到函数上的过程,叫做“闭合(closure)”

也就是那个函数在原本的作用域已经结束之后被执行,它依然能访问这些变量。

通俗点说:

  • 函数里用了不属于自己的变量 → 自由变量

  • 把这些变量“包”进来 → 封闭完成

  • 得到的东西就叫 闭包

举个例子

fun makeCounter(): () -> Int {
    var count = 0
    return {
        count++
        count
    }
}

//执行
val counter = makeCounter()
println(counter()) // 1
println(counter()) // 2

最后打印为啥是2

  • count是定义在makeCounter里的局部变量

  • 按理说函数返回后,count应该被销毁

  • 但实际上:

    • count被Lambda 捕获

    • Lambda变成了一个 闭包

    • count的生命周期被延长了

关键点

判断是否是闭包,三个重要的关键点

  1. 不是所有函数都是闭包

    val f1 = { 1 + 2 }          // ❌ 不是闭包
    val f2 = { x: Int -> x * 2 } // ❌ 不是闭包

    只有 捕获了外部变量 的函数才是闭包。

    var x = 10
    val f3 = { x * 2 }         // ✅ 是闭包
  2. 捕获的是「变量本身」,不是值拷贝

    var x = 1
    val f = { x }
    x = 2
    println(f()) // 2

    闭包持有的是 变量的引用

  3. 会延长变量生命周期

fun foo() {
    var x = 10
    GlobalScope.launch {
        delay(1000)
        println(x) // 还能访问
    }
}

x本来在函数结束时该销毁,因为被协程中的闭包引用 → 没销毁

内存泄漏的常见来源

小结

闭包是一个函数,其可以访问的外部变量环境

  1. Lambda不一定是闭包

  2. 闭包一定是某种函数

参考文章

AI

相关网址

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...