Reputation: 12467
How do I call a public extension function on a class that has a receiver?
interface CoroutineActivity {
// how can I call this function in example below?
fun CoroutineScope.onCreate(savedInstanceState: Bundle?)
}
class CoroutineActivityDelegate(private val coroutineActivity: CoroutineActivity) {
fun onCreate(savedInstanceState: Bundle?) {
val onCreateScope = CoroutineScope(Dispatchers.Main + Job())
// how do I call an extension function with a receiver? This doesn't compile
coroutineActivity.onCreate(onCreateScope, savedInstanceState)
}
}
Is it possible? I'd prefer CoroutineScope
to be the receiver, rather than the first parameter
Upvotes: 2
Views: 95
Reputation: 147981
Yes, it is possible.
The function you described is said to have two receivers, a dispatch receiver of type CoroutineActivity
and an extension receiver of type CoroutineScope
.
While there's no syntax to call this function by directly providing the two receivers, it can be called in a scope of its dispatch receiver type (i.e. in a scope where this: CoroutineActivity
). These scopes are:
CoroutineActivity
and its subtypes;CoroutineActivity
(or its subtypes);CoroutineActivity
(or its subtypes).In a suitable scope, you can simply call the function on an instance of CoroutineContext
.
The simplest way to do that is to use the standard library scoping functions run { ... }
or apply { ... }
, passing a lambda with receiver as follows:
coroutineActivity.run {
val onCreateScope = CoroutineScope(Dispatchers.Main + Job())
onCreateScope.onCreate(savedInstanceState)
}
Upvotes: 5