Kotlin 匿名扩展函数作为参数时的语义

Posted 匆忙拥挤repeat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 匿名扩展函数作为参数时的语义相关的知识,希望对你有一定的参考价值。

文章目录

函数中使用,与当前相同类型的 匿名扩展函数

class AnonymousExtendFun1 

    fun test1(block: AnonymousExtendFun1.() -> Unit) 
        block()
        block(this) // block() 传不传参都可以
        block.invoke(this) // invoke() 必须传参
        println("AnonymousExtendFun1.test1()")
        println("------")
    

    fun test2(block: AnonymousExtendFun1.() -> Boolean) 
        // 在当前 test2 函数作用域内,可以看作,对 AnonymousExtendFun 扩展了一个 名为 block 的函数
        this.block()
//        this.block(this) // error. 不能传参
//        this.block.invoke() // error. 没有 .invoke() 调用
        println("AnonymousExtendFun1.test2()")
        println("------")
    

    fun test3(block: (AnonymousExtendFun1) -> Boolean) 
        block(this) // 必须传参
        println("AnonymousExtendFun1.test3()")
        println("------")
    


fun main(args: Array<String>) 
    val obj1 = AnonymousExtendFun1()
    obj1.test1 
        println("call AnonymousExtendFun1.test1()")
    

    obj1.test2 
        println("call AnonymousExtendFun1.test2()")
        true
    

    obj1.test3 
        println("call AnonymousExtendFun1.test3()")
        true
    

输出

call AnonymousExtendFun1.test1()
call AnonymousExtendFun1.test1()
call AnonymousExtendFun1.test1()
AnonymousExtendFun1.test1()
------
call AnonymousExtendFun1.test2()
AnonymousExtendFun1.test2()
------
call AnonymousExtendFun1.test3()
AnonymousExtendFun1.test3()
------

函数中使用,不同于当前类型的 匿名扩展函数(通常要注意的是这种)

class AnonymousClz
class AnonymousExtendFun2 

    fun test1(clz: AnonymousClz, block: AnonymousClz.() -> Unit) 
        block(clz) // 必须传参
        block.invoke(clz) // invoke() 必须传参
        println("AnonymousExtendFun2.test1()")
        println("------")
    

    fun test2(clz: AnonymousClz, block: AnonymousClz.() -> Boolean) 
        // 在当前 test2 函数作用域内,可以看作,对 AnonymousClz 扩展了一个 名为 block 的函数
        clz.block()
//        clz.block.invoke() // error.
        println("AnonymousExtendFun2.test2()")
        println("------")
    

    // 基于 test1(),匿名扩展函数的实现,可以等价转成 test3()
    fun test3(clz: AnonymousClz, block: (AnonymousClz) -> Boolean) 
        block(clz)
        block.invoke(clz)
        println("AnonymousExtendFun2.test3()")
        println("------")
    

fun main(args: Array<String>) 
	val obj2 = AnonymousExtendFun2()
    val clz = AnonymousClz()
    obj2.test1(clz) 
        println("call AnonymousExtendFun2.test1()")
    

    obj2.test2(clz) 
        println("call AnonymousExtendFun2.test2()")
        true
    

    obj2.test3(clz) 
        println("call AnonymousExtendFun2.test3()")
        true
    

输出

call AnonymousExtendFun2.test1()
call AnonymousExtendFun2.test1()
AnonymousExtendFun2.test1()
------
call AnonymousExtendFun2.test2()
AnonymousExtendFun2.test2()
------
call AnonymousExtendFun2.test3()
call AnonymousExtendFun2.test3()
AnonymousExtendFun2.test3()
------

对AnonymousClz添加一个成员函数后

class AnonymousClz 
    fun putExtra(arg: Int): AnonymousClz 
        println("AnonymousClz.putExtra($arg)")
        return this
    

class AnonymousExtendFun2 

    fun test1(clz: AnonymousClz, block: AnonymousClz.() -> Unit) 
        block(clz) // 必须传参
        block.invoke(clz) // invoke() 必须传参
        println("AnonymousExtendFun2.test1()")
        println("------")
    

    fun test2(clz: AnonymousClz, block: AnonymousClz.() -> Boolean) 
        // 在当前 test2 函数作用域内,可以看作,对 AnonymousClz 扩展了一个 名为 block 的函数
        clz.block()
//        clz.block.invoke() // error.
        println("AnonymousExtendFun2.test2()")
        println("------")
    

    // 基于 test1(),匿名扩展函数的实现,可以等价转成 test3()
    fun test3(clz: AnonymousClz, block: (AnonymousClz) -> Boolean) 
        block(clz)
        block.invoke(clz)
        println("AnonymousExtendFun2.test3()")
        println("------")
    


fun main(args: Array<String>) 
    val obj2 = AnonymousExtendFun2()
    val clz = AnonymousClz()
    obj2.test1(clz) 
        this.putExtra(1)
        println("call AnonymousExtendFun2.test1()")
    

    obj2.test2(clz) 
        this.putExtra(2)
        println("call AnonymousExtendFun2.test2()")
        true
    

    obj2.test3(clz) 
        it.putExtra(3)
        println("call AnonymousExtendFun2.test3()")
        true
    

注意,匿名扩展函数实现的,在其入参函数体中,是使用 this 指代类型对象

总结

  1. 匿名扩展函数,可以简单看作是,把当前扩展类型当作参数的 函数。
    block: AnonymousClz.() -> Boolean <==> block: (AnonymousClz) -> Boolean
  2. 匿名扩展函数作用域中,对当前扩展类型,扩展了以参数名为函数名的函数
    block: AnonymousClz.() -> Boolean 在调用时,可以 clz.block()

以上是关于Kotlin 匿名扩展函数作为参数时的语义的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin函数 ③ ( 匿名函数 | 匿名函数的函数类型 | 匿名函数的隐式返回 )

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

kotlin方法传入lambda表达式参数并调用invoke什么意思

Kotlin函数 ⑨ ( Kotlin 语言中的闭包概念 | Java 语言中函数作为参数的替代方案 )

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

Kotlin函数 ④ ( 匿名函数参数 | 匿名函数 it 关键字 )