Kotlin学习笔记(9)--Lambda 表达式与高阶函数
Lambda 表达式与高阶函数
在 Kotlin 中,Lambda 表达式和高阶函数是函数式编程的重要组成部分,它们使代码更加简洁、灵活和可复用。以下将详细介绍这两个概念及其使用方法。
Lambda 表达式
Lambda 表达式是一种简洁的方式来表示可以传递的匿名函数。Lambda 表达式的基本语法如下:
{ 参数列表 -> 函数体 }
- 参数列表:参数与类型,类似于普通函数的参数。
- ->:箭头符号,用于分隔参数列表和函数体。
- 函数体:执行的代码块,最后一行表达式的值就是 Lambda 的返回值。
示例:
// 定义一个 Lambda 表达式,计算两个整数的和
val sum = { a: Int, b: Int -> a + b }
println(sum(3, 4)) // 输出 7
// 没有参数的 Lambda 表达式
val greet = { println("Hello, Kotlin!") }
greet() // 输出 "Hello, Kotlin!"
简化语法
如果 Lambda 表达式的参数类型可以被推断,或者只有一个参数,可以进一步简化语法:
// 单一参数,可以使用 'it' 作为默认参数名
val square: (Int) -> Int = { it * it }
println(square(5)) // 输出 25
// 多个参数,类型可以被推断
val multiply = { a: Int, b: Int -> a * b }
println(multiply(3, 4)) // 输出 12
Lambda 表达式的类型推导
在很多情况下,Kotlin 可以根据上下文推断出 Lambda 表达式的参数类型和返回类型,因此可以简化 Lambda 表达式的书写。
// 在高阶函数中使用 Lambda 表达式,类型可以省略
listOf(1, 2, 3, 4, 5).filter { it > 2 }.forEach { println(it) }
// 输出:
// 3
// 4
// 5
在上面的例子中,it 是 Lambda 表达式的隐式参数,表示当前元素。如果不简化,则如下方式书写。
// 在高阶函数中使用 Lambda 表达式,类型可以省略
listOf(1, 2, 3, 4, 5).filter { it -> it > 2 }.forEach { println(it) }
// 输出:
// 3
// 4
// 5
高阶函数
高阶函数是指可以接受一个或多个函数作为参数,或者返回一个函数的函数。高阶函数允许我们将函数作为第一类公民来使用,极大地提高了代码的灵活性和可复用性。
高阶函数的定义
Kotlin 中定义高阶函数的语法如下:
kotlin
fun functionName(parameter: Type, lambda: (ParamType) -> ReturnType): ReturnType {
// 函数体
}
示例:传递 Lambda 作为参数
// 定义一个高阶函数,接受两个整数和一个操作函数
fun operateFunc(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
fun main() {
val sum = operateFunc(5, 3) { x, y -> x + y }
println(sum) // 输出 8
val product = operateFunc(5, 3) { x, y -> x * y }
println(product) // 输出 15
}
// 定义一个高阶函数,接受一个整数列表和一个函数作为参数
fun operateOnList(numbers: List<Int>, operation: (Int) -> Int): List<Int> {
val result = mutableListOf<Int>()
for (number in numbers) {
result.add(operation(number))
}
return result
}
// 使用高阶函数,传入一个 Lambda 表达式来对列表中的每个元素进行平方操作
val numbers = listOf(1, 2, 3, 4, 5)
val squared = operateOnList(numbers) { it * it }
println(squared) // 输出: [1, 4, 9, 16, 25]
// 另一个示例,传入一个 Lambda 表达式来对列表中的每个元素进行加倍操作
val doubled = operateOnList(numbers) { it * 2 }
println(doubled) // 输出: [2, 4, 6, 8, 10]
使用标准库的高阶函数
Kotlin 标准库提供了许多常用的高阶函数,如 map, filter, reduce, forEach 等,这些函数极大地简化了集合操作。
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// 使用 map 将每个元素乘以 2
val doubled = numbers.map { it * 2 } // numbers.map { it -> it * 2 } 的缩写。
println(doubled) // 输出 [2, 4, 6, 8, 10]
// 使用 filter 过滤出偶数
val evens = numbers.filter { it % 2 == 0 }
println(evens) // 输出 [2, 4]
// 使用 forEach 打印每个元素
numbers.forEach { println(it) }
/*
输出:
1
2
3
4
5
*/
}
自定义高阶函数
根据需要定义自己的高阶函数,以实现更复杂的逻辑。
示例:自定义计数函数
fun main() {
val fruits = listOf("apple", "banana", "cherry", "date")
// 使用自定义高阶函数计算长度为 6 的字符串数量
val count = fruits.customCount { it.length == 6 }
println(count) // 输出 2
}
// 定义一个扩展高阶函数,接受一个条件函数作为参数
fun List<String>.customCount(condition: (String) -> Boolean): Int {
var counter = 0
for (item in this) {
if (condition(item)) {
counter++
}
}
return counter
}
函数类型与类型推断
在 Kotlin 中,函数本身也是一种类型,可以作为变量的类型或函数的参数类型。
示例:函数类型作为变量
// 定义一个函数类型的变量
val printMessage: (String) -> Unit = { message -> println(message) }
printMessage("Hello from lambda!") // 输出 "Hello from lambda!"
// 另一种方式,使用函数引用
fun display(message: String) {
println(message)
}
val printMessageRef: (String) -> Unit = ::display
printMessageRef("Hello from function reference!") // 输出 "Hello from function reference!"
高阶函数与返回值
高阶函数不仅可以接受函数作为参数,还可以返回一个函数。
示例:返回函数的高阶函数
// 定义一个高阶函数,返回一个根据因子倍增的函数
fun getMultiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
fun main() {
val double = getMultiplier(2) // 返回一个高阶函数
val triple = getMultiplier(3)
println(double(5)) // 输出 10
println(triple(5)) // 输出 15
}
函数引用
Kotlin 允许使用已有的函数作为高阶函数的参数,这通过函数引用实现,使用 :: 语法。
示例:使用函数引用
// 定义一个普通函数
fun isEven(number: Int): Boolean {
return number % 2 == 0
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6)
// 使用函数引用作为 filter 的参数
val evens = numbers.filter(::isEven)
println(evens) // 输出 [2, 4, 6]
}
匿名函数与 Lambda 的区别
虽然 Lambda 表达式和匿名函数都可以用于高阶函数,但它们在某些情况下有细微的区别:
- 返回类型:匿名函数可以明确指定返回类型,而 Lambda 依赖类型推断。
- 标签:匿名函数可以使用
return语句返回到调用它的函数,而 Lambda 中的return只会退出 Lambda 本身。
示例:
fun main() {
val lambda = { x: Int -> x * x }
println(lambda(4)) // 输出 16
val anonymous = fun(x: Int): Int {
return x * x
}
println(anonymous(4)) // 输出 16
}

浙公网安备 33010602011771号