简体   繁体   中英

On Kotlin receiver object and extensions

I'm trying to get familiar with the more advanced kotlin features, but i don't know why my little code example compiles and prints "Test A" while not printing "Test B". Can anybody tell me why Test B is not printed?

class One{
    fun delegate(operation: One.()-> Unit){
        operation()
    }
    fun main(args: Array<String>){
    val one= One()
    fun One.doIt(){
        println("Test A")
    }
    one.delegate { doIt() } //prints Test A
    one.delegate {
        fun One.doItDifferently(){
            println("Test B")      //not printed
        }
    }
}

That's because you don't call the function .toItDifferently() , you only define it (it is a local function , ie a function defined inside another function). Modify your example to call the function:

one.delegate {
    fun One.doItDifferently(){
        println("Test B")
    }
    doItDifferently() // <- here
}

(UPD, based on the comment) You can call delegate with an anonymous function like this:

one.delegate( // note the parenthesis, not the curly braces
    fun One.(){
        println("Test B")
    }
)

You're not calling the function.

That is a local extension function on the class One and you are just declaring it. It now exists and is usable in the current scope, but does nothing by itself.

You would need to call/invoke it for it to do anything, as with any normal method:

one.delegate {
    fun One.doItDifferently(){
        println("Test B")
    }

    
}

IntelliJ will actually give you a warning that this function is never used.

Edit: as per your comment, you aren't passing the function at all. This is not possible yet if you want to return the function as reflection does not support local functions.

If you try this:

class One {
    fun delegate(operation: One.() -> KFunction<*>) {
        operation().call(this)
    }
}

fun main(args: Array) {
    val one = One()
    fun One.doIt() {
        println("Test A")
    }
    one.delegate {
        fun One.doItDifferently() {
            println("Test B")      //not printed
        }
        this::doItDifferently
    }
}

You'll get:

Exception in thread "main" kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Introspecting local functions, lambdas and anonymous functions is not yet fully supported in Kotlin reflection

This declaration

one.delegate {
    fun One.doItDifferently(){
        println("Test B")      //not printed
    }
}

will just create an empty function with a nested function. doItDifferently() is just declared, but never invoked. Hence, println("Test B") will never be executed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM