florent
07/16/2021, 9:12 PMimport kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.receiveAsFlow
import org.junit.Test
class ExampleUnitTest {
@Test
fun `kotlin language error maybe`() {
val channel = Channel<String>()
channel.receiveAsFlow()
.map { State.Content(it) as State }
.catch { emit(State.Error) }
.onStart { emit(State.Loading) }
}
sealed class State {
object Loading : State()
object Error : State()
data class Content(val content: String) : State()
}
}
If I keep the as State
the compiler mark is as unnecessary, if I remove it the code doesn't compile. Is there an alternative way to write this so it compiles? I have tried using the <> syntax but it doesn't seems to workFrancesc
07/16/2021, 11:14 PMState.Content
so the compiler infers that your flow is of type State.Content
, not State
. You have to be explicit, change it like so
fun `kotlin language error maybe`() {
val channel = Channel<String>()
channel.receiveAsFlow()
.map<String, State> { State.Content(it) }
.catch { emit(State.Error) }
.onStart { emit(State.Loading) }
}
florent
07/16/2021, 11:24 PMephemient
07/17/2021, 7:33 AMFlow<out T>
is covariant, and instead write
channel.receiveAsFlow()
.map { State.Content(it) }
.catch<State> { emit(State.Error) }
.onStart { emit(State.Loading) }
because Flow<State.Content>
is a Flow<State>
ephemient
07/17/2021, 7:35 AMchannel.receiveAsFlow()
.map { State.Content(it) }
.onEach<State> {}
.catch { emit(State.Error) }
.onStart { emit(State.Loading) }
but all of this is effectively the same, just influencing Kotlin's type inferenceephemient
07/17/2021, 7:38 AM