kotlin: 再看 lambda

不得不说,kotlin 里面提供了非常多的语法糖,尤其是 lambda这块。
对于lambda,有普通的,还有带接收者的。

看下面这段代码:

fun main() {


    val str = buildString {
        append("Hello ")
        append("world !")
    }
    println("str = $str")

    val str1 = buildStr {
        it.append("hello ").append("kotlin .")
    }

    println("str1 = $str1")

    println("buildStr1 = ${buildStr1 { it.append("hello ").append("duck @") }}")

    val action: StringBuffer.() -> StringBuffer = { append("!") }
    // 定义与使用 lambda 类型的变量
    println("action -- ${StringBuffer("hi").action()}")

    println("buildStr3 = ${buildStr3 { append("hello ").append("country #") }}")

}

/**
 * 带接收者的 lambda
 */
// action: obj.() -> obj1
// String. (Int , Int) -> Unit  -- 带接收者的 lambda
fun buildString(builderAction: StringBuffer.() -> StringBuffer): String {

    val sb = StringBuffer()
    return sb.builderAction().toString()
}

fun buildStr3(builderAction: StringBuffer.() -> Unit): String =
    StringBuffer().apply { builderAction() }.toString()


/**
 * 普通 lambda
 */
// action: (obj) -> obj1
fun buildStr1(builderAction: (StringBuffer) -> StringBuffer): String {
    val sb = StringBuffer()
    return builderAction(sb).toString()
}

fun buildStr(builderAction: (StringBuffer) -> Unit): String {
    val sb = StringBuffer()
    builderAction(sb)
    return sb.toString()
}

代码就不解释了,注释里面做了部分说明。

看输出:

str = Hello world !
str1 = hello kotlin .
buildStr1 = hello duck @
action -- hi!
buildStr3 = hello country #

Process finished with exit code 0

对于 作为函数参数的 普通lambda 或者 带接收者的lambda ,我认为无论是定义还是调用都比较方便,也比较容易理解。

但是,对于定义的 带接收者的lambda 变量,与使用。理解起来就有点困惑了。(虽然还是可以理解)

可以看出 ,带接收者的 lambda与扩展函数有类似的地方,就是都定义了接收者。

关于 带接收者的 lambda

  • 作为函数参数的时候:接收者成为了这个 lambda的实际调用者。
  • 作为变量的时候:需要定义一个接收者类型的对象去调用该变量。

为什么这里是说调用变量。因为这是一个函数类型的变量。
扩展一下:调用这个变量总是无参调用吗?**不一定!**根据实际定义的lambda来,如果定义的(带接收者的)lambda里面定义了参数,那么在调用的时候就需要传参数进去。

总体来说,语法糖简化了表达。

不过对于StringBuffer().apply { builderAction() }.toString() 这种,总感觉各种括号堆在一块也不是很好看。而且,想要理解这句代码的话,得明白 apply干了啥,以及自定义的builderAction是什么。

update: 可以改成好看一点的调用格式:


fun buildStr3(builderAction: StringBuffer.() -> Unit) =
    StringBuffer().apply(builderAction).toString()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值