一句话总结
Lambda 就是「一段可以当快递传递的代码」,你可以把它塞进变量、传给函数,或者随时拿出来执行,让代码更灵活简洁。
一、核心特点:匿名、可传递、可捕获
Kotlin 的 Lambda 是一种没有名字的函数,它使函数可以像变量一样被传递和操作。
- 匿名函数:Lambda 表达式不包含函数名,直接定义其输入和输出。
- 一等公民:Lambda 可以被赋值给变量、作为参数传递给其他函数,或者从函数中返回。
- 闭包(Closure) :Lambda 可以捕获其定义时的外部作用域的变量。这使得 Lambda 可以访问其外部的局部变量,即使在外部函数执行完毕后,Lambda 仍能持有这些变量的引用。
// Lambda 捕获外部变量
fun createGreeting(name: String): () -> Unit {
return {
println("Hello, $name!") // Lambda 捕获了外部的 name 变量
}
}
val greet = createGreeting("Alice")
greet() // Output: Hello, Alice!
二、语法结构与简化规则
Lambda 的基本语法是 { 参数列表 -> 函数体 }。Kotlin 编译器提供了多种语法糖来简化 Lambda 的书写。
- 参数类型推断:如果编译器能够从上下文推断出 Lambda 的参数类型,你可以省略参数类型。
- 单参数
it:当 Lambda 只有一个参数时,你可以省略参数名,并使用隐式的it来引用这个参数。 - 尾随 Lambda:如果一个 Lambda 是函数调用的最后一个参数,你可以将它移到函数调用的括号之外。
val numbers = listOf(1, 2, 3)
// 标准写法
numbers.filter({ number: Int -> number > 1 })
// 简化写法
numbers.filter { it > 1 } // 省略参数类型、参数名,使用 it,并移到括号外
三、实际应用场景
Lambda 是 Kotlin 编程中无处不在的工具,它让代码更具表现力。
- 集合操作:
map、filter、forEach等函数都依赖 Lambda 来进行数据处理。 - 事件回调:
setOnClickListener等事件监听器,通常都以 Lambda 作为回调参数,简化了事件处理代码。 - 异步操作:在协程中,Lambda 被用于定义后台任务,如
launch { ... }和async { ... }。 - 延迟执行:将代码块作为参数传递,让它在未来的某个时间点执行。
四、高级概念与注意事项
inline内联函数:默认情况下,Lambda 会被编译为匿名内部类。对于频繁调用的 Lambda,这会产生额外的性能开销。inline关键字可以强制编译器将 Lambda 的代码直接复制到调用处,从而消除这种开销。- 非局部返回:在内联函数中,Lambda 允许使用
return直接从外层函数返回。这种行为称为“非局部返回”,它提供了强大的控制流能力。 - 内存泄漏:当 Lambda 捕获外部变量时,需要特别注意内存泄漏问题。例如,如果一个生命周期较长的对象(如单例)持有了一个捕获
Activity引用的 Lambda,那么Activity将无法被垃圾回收。
五、总结
Kotlin 的 Lambda 是函数式编程的核心。它不仅简化了代码,更重要的是,它改变了我们的编程思维,使我们能够将行为作为参数传递,从而编写出更灵活、更具表现力的代码。正确理解和使用 Lambda,是掌握现代 Kotlin 开发的关键一步。