作为一个kotlin初学者进行函数使用的时候总会产生疑问:
val mutableListOf = mutableListOf(1, 2, 3)
mutableListOf.forEach {
println("item:$it")
}
上面代码含义是new一个list,然后再for循环
forEach点进去是这样的:
@kotlin.internal.HidesMembers
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
完全看不懂啊同志们,这是啥啊,java里一般来说都是(){},()里是参数,但是为什么是{},没有(),没有参数呢?
原来这里隐含了一个东西叫做匿名函数或者说是lambda表达式,我的理解是lambda是一段可以被当作参数传递的函数,假设方法A把lambda传递给了方法B,B就可以通过lambda把数据返回给A,类似java的接口回调。
清楚了基本概念以后,现在看forEach的参数:
action: (T) -> Unit
这是什么意思呢?
action:lambda的名字
T:泛型,这里指的是list的value
Unit:类似java的void
所以我们需要给forEach传递的是一个名字叫做action的(名字也可以不一致,这里kotlin不强制要求),参数是list的value,返回值为Unit的lambda
那么按照java的思路应该是这样的:
mutableListOf.forEach(::action)
fun action (i:Int){
println("item:$i")
}
对嘛,这才是我们熟悉的接口回调(注 ::的意思是把action作为一个对象处理)
但是我们开始的时候为什么这样写:
mutableListOf.forEach {
println("item:$it")
}
原来是因为kotlin特有的语法是这样的:
去掉括号,参数int因为只有一个所以是可以隐藏的,默认是it,当然你也可以给他重命名:
mutableListOf.forEach { x: Int ->
println("item:$x")
}
我们这里就不给他重命名了,就用it就好,这个写法就是这样的记住就好了
本来我以为我已经理解了lambda了,但是当我看到这个的时候又不淡定了:
val map = mapOf(Pair("Derry", 123), Pair("Kevin", 456), "Leo" to 789)
map.forEach { (key, value) ->
println("key:$key, value:$value")
}
注:Pair可以理解为携带两个参数的bean
(key, value) ->
这又是什么写法?难道是解构?
解构是kotlin特有的一种写法:
val mutableListOf = mutableListOf(1, 2, 3)
val (x, y, z) = mutableListOf
println("item1:$x,item2:$y,item3:$z")
还是刚才的例子,就是把列表的每个参数通过这样的写法赋值,并可以使用
那(key, value) ->是不是解构的写法呢?我们来验证一下:
首先我们进去源码看map的forEach需要什么参数:
public inline fun <K, V> Map<out K, V>.forEach(action: (Map.Entry<K, V>) -> Unit): Unit {
for (element in this) action(element)
}
可以看到参数是:Map.Entry<K, V>
那好了
map.forEach { x ->
val (k, v) = x
println("key:${k}, value:${v}")
}
我们换成更熟悉的写法,x为Map.Entry<K, V>,然后再把x给解构了,最后也可以得到key和value
所以我认为(key, value) ->无非就是把解构的过程直接写道参数的位置了,现在终于对lambda的理解又深入了一些。
本文纯原创,可能会存在一些纰漏,如果有错误或者不足的地方欢迎指正。