JP
03/22/2020, 6:22 AMimport kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.selects.*
suspend fun selectAorB(a: ReceiveChannel<String>, b: ReceiveChannel<String>): String =
select<String> {
a.onReceiveOrNull { value ->
if (value == null)
"Channel 'a' is closed"
else
"a -> '$value'"
}
b.onReceiveOrNull { value ->
if (value == null)
"Channel 'b' is closed"
else
"b -> '$value'"
}
}
fun main() = runBlocking<Unit> {
val a = produce<String> {
repeat(4) { send("Hello $it") }
}
val b = produce<String> {
repeat(4) { send("World $it") }
}
repeat(8) { // print first eight results
println(selectAorB(a, b))
}
coroutineContext.cancelChildren()
}
The compiler gave warning that onReceiveOrNull
was deprecated:
'onReceiveOrNull: SelectClause1<E?>' is deprecated. Deprecated in favor of onReceiveOrClosed and onReceiveOrNull extension
I guess this is not yet applied in the guide from the documentation. May I ask how I should change the code?
suspend fun selectAorB(a: ReceiveChannel<String>, b: ReceiveChannel<String>): String =
select<String> {
a.onReceiveOrClosed {
if (it.isClosed)
"Channel 'a' is closed"
else
"a -> '${it.value}'"
}
b.onReceiveOrClosed {
if (it.isClosed)
"Channel 'b' is closed"
else
"b -> '${it.value}'"
}
}
Would this be the preferred way for now?tseisel
03/22/2020, 12:51 PMonReceiveOrNull
. There is an extension on Channel<T : Any>
that is not deprecated, but rather hard to use (because the member function is picked first), you need to import the function with an alias
If your channel contains nullable values you could use onReceiveOrClosed
, but test thoroughly as this function returns an inline class (still an experimental language feature)