Reputation: 93
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
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
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