Home > Blockchain >  Can we have an extension function for suspend function?
Can we have an extension function for suspend function?

Time:12-04

if i use :

suspend fun <T> A(block: suspend () -> T){
///std.
}

all things go right but :

suspend fun <T> (suspend () -> T).A(){
///std.
}.

no compilation errors , but i cant use it with suspend functions.

for example that we have this fun (do work is a suspend function):

accountManager.doWork(password)

in case #1 its works fine:

A {
accountManager.doWork(password)
}

in case #2 it does not work as expected(compilation error):

accountManager.doWork(password).A()

CodePudding user response:

The receiver of

accountManager.doWork(password).A()

is whatever doWork(password) returns, not the doWork function itself. Let's suppose that doWork returns String, then the above would have worked if A were an extension function on String:

// Depending on what you do in its implementation, 
// A does not need to be a suspending function
fun String.A() {

}

If you want A's receiver to be the function doWork instead, the syntax is:

(accountManager::doWork).A()

Then the above will compile if A is declared like this:

suspend fun <T, R> (suspend (T) -> R).A() {

}

Notice that the receiver type is a function that takes one parameter, since doWork takes one parameter.


If what you actually want to do is to use the entire suspending lambda you passed to A as a parameter here...

A {
    accountManager.doWork(password)
}

...as the receiver of the new extension function A that you are declaring, then your attempt is correct:

suspend fun <T> (suspend () -> T).A(){

}

You should call it on a suspending lambda:

suspend { accountManager.doWork(password) }.A()

Though I'm not sure why you would prefer this to the way more readable A { ... } syntax.

  • Related