Kotlin中,理解T.()->Unit 、 ()->Unit与(T) -> Unit

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin中,理解T.()->Unit 、 ()->Unit与(T) -> Unit相关的知识,希望对你有一定的参考价值。

参考技术A Kotlin比Java更方便的地方,其中之一是可以将函数作为参数。
上面三者都是将函数作为其它函数的参数来使用,其形式虽然简单,但理解并不简单。
一、共同点
三者的返回值相同,均为Unit,即没有返回值。
当然有返回值也可以,比如返回一个泛型R,或者是一个具体的值Int等
如:

但是这不是重点,要理解三者,主要是分析前面的部分,这里返回Unit只是为了方便理解。
二、定义形式
可以结合Kotlin自带的作用域函数来理解:
apply:

also:

自定义一个使用()->Unit的例子:

三、使用

上面的例子说明了以下几点:
1、T.()->Unit 的函数体中可以直接使用T代表的对象,即用this代表对象
2、(T) -> Unit 将T表示的对象作为实参通过函数参数传递进来,供函数体使用
3、 ()->Unit与T表示的对象没有直接联系,只能通过外部T实例的变量来访问对象

四、理解
T.()->Unit 中用this代表对象,而this的使用一般是一个类的成员函数中用来表示该类的实例对象本身,比如,为Person类加一个函数:

所以我们可以这样理解,T.()->Unit相当于是给类T定义了一个扩展函数,该函数没有形参,没有返回值,当然我们也可以增加参数与返回值,道理是一样的。
正是因为T.()为T的扩展函数,所以可以在函数体里直接访问T对象的属性或者成员函数。

(T) -> Unit与 ()->Unit只是一个普通的函数,一个带有参数,类型为T,另一个没有参数而已。
(T) -> Unit在使用it表示实参,是Lambda表达式所规定

五、总结
1、()->Unit与(T) -> Unit是相同的,只是一个带参,一个不带参
(T) -> Unit通过形参T可将对象作为实参传给函数,所以函数体里能通过it或者指定名称的方式来访问该对象

2、T.()->Unit 等同于为T定义了一个无参数的扩展函数,所以在函数体内可以直接通过this或省略来访问T代表的对象

Kotlin扩展函数T.()作为参数的理解

a:T.() ->Unit 就是T类型的一个匿名扩展函数,他的使用也必须是T对象(比如t是T的一个对象)t.() 调用
它效果等价于a:(T)->Unit 但是用法就不一样了,这样就是普通函数,使用时候是a(t对象)方法传入对象,扩展函数使用是t.a()

  var test:CoroutineScope.() -> Unit=



	fun test01()
//        test()//报错
        test(MainScope()) //正常调用
        GlobalScope.launch 
            test()//test就是CoroutineScope的扩展函数,在CoroutineScope函数内就可以直接调用,他其实就是this.test() 因为this可以省略,还是就是扩展函数,对象.方法在使用
        
    

/*
public inline fun T.apply(block: T.() -> Unit): T
contract
callsInPlace(block, InvocationKind.EXACTLY_ONCE)

block()
return this

第一,认识到apply这个方法需要传入一个函数
第二,这个函数是不是扩展函数还是什么函数都一样,都是函数就行
第三,T.() 和(T) 写法,在使用apply方法时候,传递参数是一样的,传递的是同一个函数类型
第四,block: T.() -> Unit 表示给T扩展一个叫block的扩展函数

     block 是T的扩展函数,他只能在 本次函数体内调用

    
        contract 
            callsInPlace(block, InvocationKind.EXACTLY_ONCE)
        
        block()
        return this
    

     离开这个范围,block 这个T的扩展函数就没办法访问了
     因为apply也是T的扩展函数,所以block这个T的扩展函数 也就可以直接调用了,默认就表示当前对象在调用自己的block
     

    block: T.() -> Unit  翻译一下就是  T.block()  写了一个只在apply这个方法体内能够访问的扩展函数
    fun <T> T.apply(block: T.() -> Unit): T
    这个方法定义 就类似  fun <T> T.apply(block: (T) -> Unit): T
    他接受的是一个函数,恰好,这个函数如果是这样写法T.() ,这个函数就是T的一个扩展函数,反正我们要传一个函数就去就行
    比如
        var aa=fun(s:String)
        Log.i("lmj",s+"tag")
    

    "111".apply(aa)  这里就表示 扩展函数aa 被传递到apply,apply在被对象"111".apply这样调用时候,就执行了aa
     也就是执行了apply函数体内的block()

*/

以上是关于Kotlin中,理解T.()->Unit 、 ()->Unit与(T) -> Unit的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin扩展函数T.()作为参数的理解

kotlin T.()

Kotlin、Proguard 和 lambdas

Kotlin标准库函数 ① ( apply 标准库函数 | let 标准库函数 )

Kotlin 流 倒计时

测试是否调用通过函数参数传递的函数(Android / Kotlin))