1、lambda表达式
fun main(args: Array<String>) {
val a=10
val b=5
//m,n,还有返回值的类型由函数的定义可以推断出来,可以省略不写
println(cacl(a, b, { m:Int, n:Int ->Int
m + n
}))
println(cacl(a, b, { m, n ->
m - n
}))
}
fun cacl(a:Int,b:Int,block:(Int,Int)->Int):Int{
val result=block(a,b)
return result
}
输出:
image.png
2、去括号
调用的时候如果最后一个参数传递的是匿名函数lambda表达式的话, 可以把()前移
fun main(args: Array<String>) {
val a=10
val b=5
//m,n,还有返回值的类型由函数的定义可以推断出来,可以省略不写
println(cacl(a, b) { m:Int, n:Int ->Int
m + n
})
println(cacl(a, b){ m, n ->
m - n
})
}
fun cacl(a:Int,b:Int,block:(Int,Int)->Int):Int{
val result=block(a,b)
return result
}
输出:
image.png
3、lambda表达式单独存在
fun main(args: Array<String>) {
//定义并调用
{
println("匿名函数、lambda表达式")
}.invoke()
//有参数lambda表达式
val result={a:Int,b:Int->
a+b
}(10,20)
println(result)
//保存lambda表达式
val function={
println("hello,world")
}
function.invoke()
}
输出:
image.png
4、返回值
lambda表达式的返回值是最后一行,不需要写return
5、lambda表达式演变流程
fun main(args: Array<String>) {
var str="abc"
str.forEach {
println(it)
}
}
输出:
image.png
看下forEach中这个lambda表达式的演变流程
首先看下forEach这个函数的定义
/**
* Performs the given [action] on each character.
*/
public inline fun CharSequence.forEach(action: (Char) -> Unit): Unit {
for (element in this) action(element)
}
很明显
- 它是个扩展函数
- 它接收的参数是一个函数类型,这个函数有一个参数char并且没有返回值
所以我们可以这样写:
fun main(args: Array<String>) {
var str="abc"
str.forEach(::print)
}
fun print(c:Char)
{
println(c)
}
输出:
image.png
我们把print定义成匿名函数:
fun main(args: Array<String>) {
var str="abc"
str.forEach(result)
}
val result={
c:Char->
println(c)
}
输出:
image.png
继续简化,不预先定义result函数,在调用forEach传参数的时候再定义result函数
fun main(args: Array<String>) {
var str="abc"
str.forEach({
c:Char->
println(c)
})
}
继续简化,参数的最后一个如果是lambda表达式,那么括号可以前移
fun main(args: Array<String>) {
var str="abc"
str.forEach(){
c:Char->
println(c)
}
}
前移之后如果函数没有了参数,那么括号可以省略
fun main(args: Array<String>) {
var str="abc"
str.forEach{
c:Char->
println(c)
}
}
如果lambda表达式只有一个参数,那么参数可以省略,用it代替
fun main(args: Array<String>) {
var str="abc"
str.forEach{
println(it)
}
}
最后的,也就是我们经常使用到的写法