lambda表达式
高阶函数
高阶函数就是接受一个函数为参数,或者返回一个函数。
fun caculate(a: Int, b: Int, calc: (a: Int, b: Int) -> Int) {
println(calc(a, b))
}
fun main() {
caculate(1, 2){ a, b -> a + b }
caculate(1, 2){ a, b -> a - b }
caculate(1, 2){ a, b -> a * b }
caculate(1, 2){ a, b -> a / b }
}
lambda表达式的返回值
在默认情况下,lambda表达式的最后一条语句的返回值会作为该lambda表达式的返回值,我们可以通过全限定的return语法来显示的指定返回值。
fun main() {
var strings = arrayOf("hell", "hello", "a", "world")
strings.filter { it.length > 3 }
strings.filter { return@filter it.length > 3 }
}
匿名函数
匿名函数的方法体是一个表达式时,可以省略返回值,编译器能够推导出来。
匿名函数的方法体是一个代码块时,不能省略返回值,编译器能够推导出来。
匿名函数的参数类型有时也能被省略(如果能从上下文中推导的话)。
package com.morris.kotlin.lambda
fun main() {
fun(a: Int, b: Int) = a + b
fun(a: Int, b: Int): Int {
return a + b
}
var strings = arrayOf("hell", "hello", "a", "world")
strings.filter(fun(it) = it.length > 3).forEach(fun(it) = println(it))
}
闭包
lambda表达式或者匿名函数内部能修改外部的变量。
fun main() {
var sum = 0
var strings = arrayOf("hell", "hello", "a", "world")
strings.forEach { sum += it.length }
println(sum)
}
带接收者的函数字面值
kotlin提供了这样一种功能:可以通过指定的接收者对象来调用一个函数字面值,在函数字面值内部,你可以调用接收者内部的方法(this)而无需使用任何额外的修饰符。
var sum: Int.(Int)->Int = { this + it }
println(1.sum(10))
匿名函数也可以指定函数字面值的接收者类型,这样我们就可以先去声明一个带有接收者的函数型变量,然后再去使用它。
var sum2 = fun Int.(other: Int): Int = this + other
println(1.sum2(10))
带有接收者类型的函数的非字面值可以作为参数进行传递,前提是所需要接收函数的地方有一个接收者类型的参数,反之亦然。
比如说:类型String.(Int)->Boolean与(String, Int)->Boolean等价。
val myEquals: String.(Int) -> Boolean = { this.toIntOrNull() == it }
println("456".myEquals(456)) // true
fun myTest(op: (String, Int) -> Boolean, a: String, b: Int, c: Boolean) = op(a, b) == c
myTest(myEquals, "123", 123, true)