Kotlin-Lambda表达式

之所以我觉得Kotlin有点为了语法糖而语法糖的地方就在这里,一个Lambda表达式有五种写法。。。虽然是一步步根据语法糖演变过来的,但是我还是记的相当痛苦。

  • Lambda:一小段可以作为参数传递的代码,语法结构为:
    {参数名1: 参数类型,参数名2:参数类型 -> 函数体}
    这是完整的Lambda表达式的定义公式,函数体的最后一行代码就是该Lambda表达式的返回值!当然还有简化版的啦,做一个找出 一个数组里长度最长的单词的函数的话,用Lambda表达式应该这么写:
fun main() {
    val list = listOf("a", "asd", "dsaf", "sd", "sdfsadfsad", "sdafsdafsadfsafds")
    val lambda = { s: String -> s.length }
    val result = list.maxBy(lambda)
    println(result)
}

首先定义一个数组,随便写几个字符串,然后定义一个Lambda表达式语句,按照刚才完整的公式定义出来的,接下来开始简化,首先不需要定义额外的lambda变量来接收Lambda表达式语句,直接丢进maxBy函数里面就行:

fun main() {
    val list = listOf("a", "asd", "dsaf", "sd", "sdfsadfsad", "sdafsdafsadfsafds")
    val result = list.maxBy({ s: String -> s.length })
    println(result)
}

然后Kotlin规定,当Lambda表达式是该函数的最后一个参数的时候,可以把Lambda表达式移到括号外面:

val result = list.maxBy(){ s: String -> s.length }

接下来,如果Lambda是该函数的唯一一个参数时,可以将括号省略:

val result = list.maxBy{ s: String -> s.length }

然后由于Kotlin有出色的类型推导机制,所以String类型的声明也可以省略:

val result = list.maxBy { s -> s.length }

最后!最终简化版就要来了!如果该Lambda表达式只有一个参数的时候,可以不给形参定义名字,用默认的it关键字来代替:

 val result = list.maxBy { it.length }

其实看了之后觉得,嗯。。。还是挺爽的哈哈

  • Java函数式API
    我举个栗子,在Java中要开启一个子线程的话,需要这么写:
new Thread(new Runnable() {
            @Override
            public void run() {
				doSomething();
            }
        }).start();

在JDK1.8之后加入了Java的Lambda表达式之后是这样子:

new Thread(() -> {
   doSomething();
}).start();

而在Kotlin中呢,,最终简化版是这样的:

Thread{
  doSomething()
}

也是由标准的Lambda表达式公式定义,然后一步一步的演变成这么简单的,你可以自己演变一下。

Kotlin还有强大的空指针检查系统,所有的参数默认情况下统统不能为空,Kotlin将空指针的检查提前到了编译期!

但是总是有些地方需要可以为空的参数的,这个时候可以在参数类型后面加个问号:

fun doStudy(study: Study?) {
    study.readBooks()
    study.doHomework()
}

回到刚才的doStudy方法,在Study后面加个问号,就可以传null了,但是编译会报错:
在这里插入图片描述
它说只有?.和非空的调用才被允许,等等,这个?.是个啥??其实是当当前对象不为空的时候才调用后面的方法的意思,这个和我在写Flutter的时候Dart语言一毛一样。说到?.操作符,那不得不提到let函数了,let函数是将原始的调用对象当做参数传到lambda表达式中作为形参,这么说有点绕,举个栗子:

fun doStudy(study: Study?) {
    study?.let { obj ->
        obj.readBooks()
        obj.doHomework()
    }
}

这里的lambda表达式里面的obj就是外面的study,明白了吧,这么做的好处就是我只用进行一次?.的调用就可以做到空指针安全了,不为空的情况下才会进入到lambda表达式。

当当前对象为空时,如果你想返回一个默认值的情况下,可以用?:操作符,?:操作符后面的值就是当对象为空的时候的返回值,举个例子:
在这里插入图片描述
如果我们传入student对象,那么打印出来的当然就是readBooks()方法的返回值:read books

如果我们传入null的话:
在这里插入图片描述
这就是?:的用法,在Dart语言里面则是 ??双问号。

还有一种方法就是强行通过编译,使用!!.操作符:
在这里插入图片描述
!!.的意思就是告诉Kotlin,我很确定这个对象不会为空,用不着你来帮我做非空检查,出了问题劳资负责,你直接抛空指针异常吧!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值