Step 1 of 5 · Reading · ~2 min
Learn
Coroutines
Coroutines need ways to talk. Kotlin offers two:
Channel<T> — like a Go channel. Producers send, consumers receive:
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>()
launch {
for (i in 1..5) ch.send(i * i)
ch.close()
}
for (sq in ch) {
println(sq)
}
}
for-in over a channel receives until close. Channels are lazy and one-shot — once consumed, the value is gone.
Flow<T> — cold async stream. Like a sequence but with suspend:
import kotlinx.coroutines.flow.*
fun squares(n: Int): Flow<Int> = flow {
for (i in 1..n) {
delay(10) // can suspend inside
emit(i * i)
}
}
fun main() = runBlocking {
squares(5).collect { value ->
println(value)
}
}
Cold = doesn't run until collected. Each collect re-runs the producer. Compare to channels which are hot.
Flow operators:
flow.map { it * 2 }
.filter { it > 5 }
.take(3)
.collect { println(it) }
flowOn(dispatcher) — change which thread the upstream runs on:
flow { ... }
.flowOn(Dispatchers.IO) // upstream on IO
.map { ... } // map on whatever collected with
.collect { ... }
StateFlow / SharedFlow — hot variants:
StateFlow<T>— reactive state holder, always has a valueSharedFlow<T>— multi-subscriber event stream
Used heavily in Android with Jetpack Compose / ViewModels.
Channels vs Flow:
- Channel — for hand-off between specific coroutines. Hot.
- Flow — for emission streams transformed with operators. Cold (or use Shared/StateFlow for hot).
What this grader actually has
Channel and Flow both live in kotlinx.coroutines, a library that is not
on this grader's classpath — import kotlinx.coroutines.flow.* fails with
unresolved reference: kotlinx. The stdlib's Sequence is the closest thing
you can run here:
val total = listOf(1, 2, 3, 4, 5).asSequence()
.filter { it % 2 == 0 }
.map { it * it }
.toList()
.sum() // 20 — nothing ran until toList() asked
A Sequence is cold and lazy exactly like a Flow: the pipeline does nothing
until a terminal operation pulls on it, and each terminal operation re-runs
it. What a Flow adds on top is suspension — a Flow can delay, await I/O
and be collected from a coroutine, which a Sequence cannot.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…