jtsalva
jtsalva

Reputation: 93

How to pass generically scoped suspend lambda to class method in Kotlin?

Want to have a function inside an open class which can accept a suspend lambda and run it.

I know this works when you specify the type explicitly but if possible need it to accept generically scoped lambdas.

class ChildClass : SuperClass() {

    // does work :)
    fun launch(block: suspend ChildClass.() -> Unit) =
        coroutineThing { this.block() }

}
open class SuperClass {

    // doesn't work :(
    fun <T : SuperClass> launch(block: suspend T.() -> Unit) = 
        coroutineThing { this.block() }

}

The error I am getting is Expression 'block' of type 'suspend T.() -> Unit' cannot be invoked as a function. The function 'invoke()' is not found.

Edit:

Looking to eventually call this method from an instance of the ChildClass like this: ChildClass().launch { doStuff() }

Upvotes: 1

Views: 816

Answers (2)

Andrei Tanana
Andrei Tanana

Reputation: 8442

You can write like this but I don't know how it works :) For me, it looks like Kotlin issue.

open class SuperClass {
    fun <T : SuperClass> launch(block: suspend T.() -> Unit) =
        coroutineThing { block.invoke(this as T) }
}

but in that case you have to invoke it like this:

ChildClass().launch<ChildClass> { println("test") }

but you can change it a bit to invoke it like you want:

open class SuperClass<T : SuperClass<T>> {
    fun launch(block: suspend T.() -> Unit) =
        coroutineThing { block.invoke(this as T) }
}

class ChildClass : SuperClass<ChildClass>()

//invokation
ChildClass().launch { println("test") }

Upvotes: 3

Ninja420
Ninja420

Reputation: 3892

How about this ?

open class SuperClass {


    fun<T: SuperClass> launch(superClass: T, block: suspend T.() -> Unit) {
        GlobalScope.launch {
            superClass.block()
        }
    }

}


open class ChildClass: SuperClass() {
    suspend fun print() {

    }
}


fun test () {
    val a = ChildClass()
    a.apply {
        launch(this) {
            print()
        }
    }
}

Upvotes: 0

Related Questions