Martin Nordholts
06/08/2020, 6:46 AMsuspend fun g(): String = "bar"
suspend fun f(mutableMap: MutableMap<String, String>) {
mutableMap.computeIfAbsent("foo") {
g()
}
}
gives me Suspension functions can be called only within coroutine body
compilation errror on the g()
call.
The only solution I can come up with is to re-implement computeIfAbsent
in Kotlin and make the fun
inline
, but that does not seem like an elegant, idiomatic solution.
What is the proper solution to this problem?octylFractal
06/08/2020, 6:48 AMcomputeIfAbsent
can do all sorts of locking and stuff that doesn't work with the suspend
mechanismoctylFractal
06/08/2020, 6:48 AMsuspend
function, you can use runBlocking
, but there's no way to cross the java boundaryMartin Nordholts
06/08/2020, 6:52 AMcomputeIfAbsent
is a regular function with simple logic that does not involve and locks or other such things: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-
And wrapping in runBlocking
does not get rid of the compilation error.octylFractal
06/08/2020, 6:52 AMoctylFractal
06/08/2020, 6:52 AMConcurrentHashMap
octylFractal
06/08/2020, 6:53 AMMartin Nordholts
06/08/2020, 6:53 AMoctylFractal
06/08/2020, 6:54 AMMartin Nordholts
06/08/2020, 6:55 AMwithContext(<http://Dispatchers.IO|Dispatchers.IO>)
it is not that big of a deal to use runBlocking
octylFractal
06/08/2020, 6:56 AMMartin Nordholts
06/08/2020, 6:56 AMConcurrentHashMap
in the general case of course. Although in my case that is not usedoctylFractal
06/08/2020, 6:56 AMDominaezzz
06/08/2020, 6:57 AMrunInterruptible(<http://Dispatchers.IO|Dispatchers.IO>) { }
then cancellation will work across the java boundary.octylFractal
06/08/2020, 6:57 AMelizarov
06/08/2020, 8:36 AMConcurrentHashMap
then just replace Javas computeIfAbsent
with Kotlin’s inline getOrPut