Reputation: 23871
All of the following examples require a mutex variable.
val mutex = Mutex()
If I have an non-suspend function, I can use it create a synchronzied suspend function:
fun action0 () {}
suspend fun synchronizedAction0 () {
mutex.withLock {
action0 ()
}
}
The same applies to functions with arguments:
fun action1 (x: T) {}
suspend fun synchronizedAction1 (x: T) {
mutex.withLock {
action1 (x)
}
}
If I have more than one non-suspend function, I want to convert into synchronized versions, I can write a non-suspend function, which takes another non-suspend function and converts it into a suspend function.
fun synchronize (action0: () -> Unit): suspend () -> Unit {
return suspend {
mutex.withLock {
action0 ()
}
}
}
But how to do it for an action, which requires an argument?
I tried this, but it does not compile:
fun synchronize (action1: (T) -> Unit): suspend (T) -> Unit {
return suspend { x ->
mutex.withLock {
action1 (x)
}
}
}
The error is, that the compiler can not infer the type of parameter x
. I think it is obvious, it is T
. How can I tell Kotlin?
I tried this, but it does not compile either.
fun synchronize (action1: (T) -> Unit): suspend (T) -> Unit {
return suspend fun (x: T) {
mutex.withLock {
action1 (x)
}
}
}
What is the right syntax?
Upvotes: 0
Views: 170
Reputation: 28462
First of all, we need to define T
as a type parameter for the synchronize()
function. Then we don't really have to specify suspend
or argument types for the lambda - they will be automatically inferred by the compiler:
fun <T> synchronize (action1: (T) -> Unit): suspend (T) -> Unit {
return { x ->
mutex.withLock {
action1 (x)
}
}
}
Upvotes: 2