kotlin标准库函数支持lambda.

kotlin标准库韩式本质上都是扩展函数,而"接收者"是与扩展函数相关的术语

let

let能使某个变量作用于其lambda表达式中,以便it关键字能方便引用它。

生成一个简单的随机用户名:

val username = "user".let { it + Random.nextInt(1000,9999) }
println(username) //user525

let结合其它kotlin语法使用非常方便: 

fun welcomeVip(uservip:String?):String {
    return uservip?.let { "hell0, $uservip" } ?: "Welcome home"
}

also

also功能与let类似,also也是把接收者作为值参传递给lambda

区别是also返回接收者对象,而let返回lambda结果

var listData = listOf(0, 1, 2, 3, 4, 5)
        .also {
            print(it.size) // 6
        }.also {
            print(" - ${it.last()}") // - 5
        }.also {
            println(" - ${it.last() * it.first()}") //- 0
        }
println(listData) //[0, 1, 2, 3, 4, 5]

由于also返回的是接收者对象,因此可以基于原始对象进行更多链式调用

apply

apply函数可以看做是一个配置函数,

apply可以传入一个接收者,然后调用一系列函数来配置它以便使用

val listBase = listOf(null,0,1,2,3,4,5,6)
println(listBase.last()) // 6
println(listBase.first()) // null
println(listBase.indexOf(3) * listBase.indexOf(4))  //2 * 3

上面是一个不使用apply情况下使用list元素的例子

下面对比一些使用apply后的效果

listOf(null, 0, 1,2,3,4,5,6).apply {
        println(last())
        println(first())
        println(indexOf(3) * indexOf(4))
}

可以看到,在调用函数类配置接收者时,变量名被省略掉了

这是因为,在lambda表达式里,apply能让每个配置函数都作用于接收者

这种行为有时又被叫做"相关作用域"

因为,lambda表达式里的所有函数调用都是针对接收者的,或者说,它们是针对接收者的隐式调用

run 

run函数和apply差不多,不同的是run函数不返回接收者,而是返回lambda的结果(true或者false)

val listBase = listOf(null,0,1,2,3,4,5,6).run { indexOf(3)>0 }
println(listBase) // true

run也能用来执行函数引用

    fun messageIsLong(name: String)  = name.length > 10
    fun messageDecode(nameTooLong:Boolean):String {
        return if(nameTooLong){
            "haha,zhangsan"
        }else{
            "hello,welcome"
        }
    }

    println("zhangsan,cyberjudge,Professor of criminal law".run(::messageIsLong))
    println("and bad example: biubiubiu".run(::messageIsLong))
    // run函数支持链式调用
    println("zhangsan,cyberjudge,Professor of criminal law".run(::messageIsLong).run(::messageDecode))
    //比较相同功能的嵌套函数
    println(messageDecode(messageIsLong("zhangsan,cyberjudge,Professor of criminal law")))

    // RUN的一种非常少见的用法:不使用接收者直接调用
    val isWelcome = run { if( messageIsLong("zhangsan"))"hello,zhangsan" else "welcome" }
    println(isWelcome)

with

wit函数是run的变体,with非常少用

不啰嗦,先看代码

    val messageTooLong = with("hellow,zhangshan"){
        length >=30
    }
    println(messageTooLong) // false

可以看到wit函数与run函数的功能行为一样,但调用方式明显不同。

调用with函数时,需要值参作为第一个参数传入。而不是像“string.run()”这样直接在对象上调用。

因此,在kotlin标准代码风格中,run函数是更优选择

takeIf

takeIf和其他标准函数有点不一样,takeIf需要判断lambda中提供的条件表达式给出的布尔结果

如果是true则从takeIf函数返回接收者对象,否则返回null

    val listData = listOf(null,0,1,2).takeIf { it.first() != null }
    println(listData) // null

takeIf类似于if语句

takeIf优势在于可以直接在对象上直接调用,避免了临时变量赋值的麻烦

takeIf还有一个兄弟函数:takeUnless

与takeIf区别是,takeUnless只判断给定的条件是否是false

    val listNotData = listOf(null,0,1,2,3).takeUnless { it.first() != null }
    println(listNotData) //[null, 0, 1, 2, 3] 这里直接返回了lest对象

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐