Hey, I’m sure there’s a valid reason why Flow
was designed this way and this might be a very newby question but I figured I’d ask anyway, I might learn something along the way.
I’ve noticed you can’t iterate over a Flow using a for loop
the same way you can iterate over a Channel
.
Which means we need to write code like this when we want to return something based on the result of the Flow
:
public suspend fun <T> Flow<T>.first(): T {
var result: Any? = NULL
try {
collect { value ->
result = value
throw AbortFlowException()
}
} catch (e: AbortFlowException) {
// Do nothing
}
if (result === NULL) throw NoSuchElementException("Expected at least one element")
return result as T
}
There’s nothing wrong with the code above but it would look nicer if it was:
public suspend fun <T> Flow<T>.first(): T {
if (hasNext()) {
return next() as T
} else {
throw NoSuchElementException("Expected at least one element")
}
}
Again, I’m only asking to learn more
If I understand correctly this can be done with channels
, I think of Flow
s as “simplier” channels as they don’t require synchronization. So, in theory, iterating over them with just a simple for loop
should be viable?