Consider this Kotlin code using flow and withContext. What will it print?
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val flow = flow { emit(1) withContext(Dispatchers.IO) { emit(2) } emit(3) } flow.collect { value -> println(value) } }
Think about how withContext affects the flow builder and emission.
The flow builder preserves the context for emissions. Using withContext(Dispatchers.IO) inside the flow block switches the coroutine context temporarily, so emit(2) runs on IO dispatcher but still emits correctly. Thus, all three values 1, 2, and 3 are emitted and printed.
What will this Kotlin code print?
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val flow = flow { emit(1) launch(Dispatchers.IO) { emit(2) }.join() emit(3) } flow.catch { e -> println("Error: $e") } .collect { value -> println(value) } }
Consider what happens when emit is called from a different coroutine launched inside the flow builder.
Emitting from a different coroutine context inside launch breaks the flow's context preservation rule. This causes an IllegalStateException with message "Flow invariant is violated" because emit must be called from the flow's coroutine context.
Identify the cause of the runtime error in this Kotlin Flow snippet:
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val flow = flow { emit(1) withContext(Dispatchers.IO) { launch { emit(2) } } emit(3) } flow.collect { println(it) } }
Look at where emit(2) is called and how coroutines are nested.
The emit(2) call is inside a launch coroutine inside withContext. This means emit(2) runs in a different coroutine context than the flow builder's coroutine, violating flow context preservation and causing a runtime error.
Choose the Kotlin code snippet that correctly emits values on different dispatchers without breaking flow context preservation.
Remember that emit must be called from the flow's coroutine context.
Option C uses withContext to switch dispatcher temporarily but keeps emit calls in the flow's coroutine context, preserving flow context. Other options launch new coroutines which break this rule.
Analyze the following Kotlin Flow code and determine how many items will be emitted and collected.
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val flow = flow { emit(1) withContext(Dispatchers.IO) { emit(2) withContext(Dispatchers.Default) { emit(3) } } emit(4) } val collected = mutableListOf<Int>() flow.collect { collected.add(it) } println(collected.size) }
Consider how nested withContext calls affect flow emissions.
All emit calls happen inside the flow builder's coroutine context, even when nested inside withContext calls. This preserves flow context, so all four items (1, 2, 3, 4) are emitted and collected. The printed size is 4.