Lambda在Kotlin中的表达式

作者: Android架构 | 来源:发表于2019-03-01 21:43 被阅读7次

    Lambda就是匿名函数,什么是匿名函数?匿名函数就是没有名字的函数,大多数情况下我们定义的函数都是具名函数(有名字的函数).
    具名函数如下

    fun sum(arg1 : Int,arg2 : Int): Int{
        return arg1 + arg2
    }
    

    这个函数的名字就叫sum.
    那匿名函数怎么定义呢, 下面就是一个匿名函数

    fun(arg1 : Int, arg2 : Int) : Int{
        return arg1 + arg2
    }
    

    这样写还不行,因为压根不知道什么时候用,所以我们需要付给一个引用,用来保存它,然后在需要使用的时候调用

    val sum = fun(arg1 : Int, arg2 : Int) : Int{
        return arg1 + arg2
    }
    

    当然既然是匿名函数,我们也可以当作参数使用, 先定义一个传入匿名函数参数的函数

    fun test(action : (Int,Int) -> Int) : Int{
        return action(1,2)
    }
    

    这里我说明一下这个参数的定义 action : (Int,Int) -> Int,它的意思是说传入一个Lambda表达式,这个Lambda表达式是传入两个int,返回一个int, 在这个函数中调用action(1,2)的意思是执行这个Lambda表达式,传入的参数是1和2

    然后传入匿名函数参数

    val result = test({arg1 : Int, arg2 : Int -> arg1 + arg2})
    println("result $result")
    

    这样传入做的运算是1+2相加后并返回3并输出.
    当然也可以这样写,更加简洁

    val result = test({arg1, arg2 ->arg1 + arg2})
    

    下面我们再来看个例子

    fun main(args: Array<String>) {
        args.forEach { 
            println(it)
        }
    }
    

    forEach这个函数很奇怪,它没有"()"去传入参数,我们来看看它是怎么实现的

    public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit {
        for (element in this) action(element)
    }
    

    其实forEach它是有参数的,这个参数就是一个类型为“action: (T) -> Unit”的函数 , 也就是传入一个T类型的参数返回一个Unit类型(Unit是无返回类型)

     for (element in this) action(element)
    

    这就是一个循环执行Lambda表达式,按照这个函数定义我们原本调用应该是这样

    args.forEach({it : String -> println(it)})
    

    简洁一下

    args.forEach({it -> println(it)})
    

    kotlin中函数最后一个参数是Lambda表达式可以提取到"()"外面,于是变成了这样

    args.forEach(){it -> println(it)}
    

    这里我们来说下it这个关键字,当一个 lambda 表达式只有一个参数的时候,你可以在你的代码中将其省略,并用 it 代替 ,这是一个很有用的特性
    于是乎就变成了这样

    args.forEach {
        println(it)
    }
    

    这还不是终极版本,最终最简洁的写法是

    args.forEach(::println)
    

    前文中提到forEach就收的是一个action: (T) -> Unit类型的函数,而println的定义是

    public inline fun println(message: Any?) {
        System.out.println(message)
    }
    

    这就是传入一个Any对象没有返回值,T一定继承自Any,println函数符合forEach参数的要求,所以我们直接用::println表示一个println引用传入给forEach.

    成员引用

    成员引用的表达方式可以让lambda的表达更加简洁. 如果我们定义一个下面的类和一个传递action: (Person) -> Unit参数的扩展函数

    fun Person.test(action: (Person) -> Unit){
        action(this)
    }
    class Person(val name : String){
        fun work(){
            println("my name is $name i am working")
        }
    }
    

    那么通常调用这个扩展函数的方式是

    val p = Person("小白")
    p.test({p:Person -> p.work()})
    

    通过成员引用的表达方式可以这样去表示

    val p = Person("小白")
    p.test(Person::work)
    

    Person::work其实是对lambda表达式{p:Person -> p.work()}的简化
    以上是我对kotlin中的Lambda表达式一点总结.希望对大家能有帮助~
    【附录】

    资料图

    需要资料的朋友可以加入Android架构交流QQ群聊:513088520

    点击链接加入群聊【Android移动架构总群】:加入群聊

    获取免费学习视频,学习大纲另外还有像高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)等Android高阶开发资料免费分享。

    相关文章

      网友评论

        本文标题:Lambda在Kotlin中的表达式

        本文链接:https://www.haomeiwen.com/subject/eanjuqtx.html