kotlin className.() 类名点花括号 T.()

一、概述

在看一些开源,或者他人的代码的时候遇到这种语法。高级函数参数里有个 类名.(),曾经也抄过放到自己的代码里。但是没有深究,一段时间后看的时候又忘记是什么意思了,so 记录一下。

二、先说结论

className.() 在高阶函数中出现,作为高阶函数的一个参数。
表示:一个以className 对象作为参数的函数或者Lambda

fun className.()
//表示的是

fun xxx(ob:className){

}

//或者
{ ob:className->

}

细节this表示见下文。

三、出现过的场景

fun ViewModel.launch(
        block: suspend CoroutineScope.() -> Unit,
        fail: (t: Throwable) -> Unit = { },
        toastNetWorkError: Boolean = GLOBAL_TOAST_NETWORK_ERROR,
        toastResponseError: Boolean = GLOBAL_TOAST_RESPONSE_ERROR
) = viewModelScope.safeLaunch(block, fail, toastNetWorkError, toastResponseError)

fun TextView.addTextChangedListenerDsl(init: TextWatcherDslImpl.() -> Unit) {
    val listener = TextWatcherDslImpl()
    listener.init()
    this.addTextChangedListener(listener)
}

出自:代码连接:KT DSL自定义

三、错误的理解

错误1:一开始和小伙伴讨论,以为是className.()表示的是className的扩展函数,来做参数。后面仔细想了下,写了个demo验证是不对的。和扩展函数没啥关系。

四、验证demo

class A {
    fun xx() {

    }
}

fun zz(s: A): Unit {
    println("zz s=$s")
}

fun String.addFun(action: A.() -> Unit) {
    val a = A()
    println("addFun a=$a")
    a.action()
}

fun String.addFun2(action: (A) -> Unit) {
    val a = A()
    println("addFun2 a=$a")
    action(a)
}

fun main(args: Array<String>) {
    val demo = ""
	//第一种
    val f1 = { a: A ->
        println("f1 a= $a")
    }
    demo.addFun(f1)
    demo.addFun2(f1)
	//第二种
    demo.addFun(::zz)
    demo.addFun2(::zz)
    
	//第三种
    demo.addFun { 
        
    }
    
    demo.addFun2 { 
        
    }
}

【补充】:高阶函数直接传函数作为参数是用双冒号::
【结论】
1、 在ide上其实看到,第三种情况见区别。1,2情况一样
demo.addFun { this:A
}

demo.addFun2 { it:A
}

这个就是 action: A.() -> Unit 和 action: (A) -> Unit 的区别。一个Lambda参数是this,一个默认参数是it。注意这里action: A.() -> Unit的参数只能是this是不能修改的。action: (A) -> Unit的可以修改。

五、进一步联想和思考

到这里发现action: A.() -> Unit 和 action: (A) -> Unit 就是lambda表示参数 this和it区别的时候

  • 一方面还想知道为什么,这个就比较深了今天估计没答案,这个涉及到A.() 的语法。
  • 另一方面突然又觉得很熟悉this, it … let,apply 【☺☺☺☺☺】

我记得自己很久以前写过一篇with和apply的:这个
打开源码就很明白了:

//this的
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}
//it的
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值