Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion kotlinx-coroutines-core/common/src/channels/Channel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,48 @@ public inline fun <T> ChannelResult<T>.onClosed(action: (exception: Throwable?)

/**
* Iterator for a [ReceiveChannel].
* Instances of this interface are *not thread-safe* and shall not be used from concurrent coroutines.
* Instances of this interface are *not thread-safe*.
* A coroutine is only allowed to call methods on those iterator instances which it instantiated.
*
* Typically, an iterator is used indirectly in the `for` loop and is not instantiated explicitly.
*
* ```
* for (element in channel) {
* // process the element
* }
* ```
*
* If your use-case requires handling the iterator directly,
* you must call [hasNext] before each [next].
* Refer to [hasNext] and [next] for more details.
*
* An example usage:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you describe the sequence of events where this sample would answer a question a user may realistically have? It neither explains the next()/hasNext() interplay useful in deeply technical cases where you'd manipulate ChannelIterator manually, nor does it spell out "hey, this is not the class that you need to use manually, just write for (... in ...) instead" if that was the intention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm addressing my own confusion with the original wording - it primed me to think that only one coroutine is allowed to create instances of the iterator.

Copy link
Contributor Author

@murfel murfel Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added wording on "don't use directly" and "next/hasNext"

*
* ```
* val channel = Channel<Int>()
* launch {
* channel.send(1)
* channel.send(2)
* channel.send(3)
* channel.close() // NB: must close for iterators to finish
* }
* launch {
* for (element in channel) {
* println("Consumer A got $element")
* }
* }
* launch {
* for (element in channel) {
* println("Consumer B got $element")
* }
* }
* ```
* Possible output:
* ```text
* Consumer A got 1
* Consumer A got 2
* Consumer B got 3
* ```
*/
public interface ChannelIterator<out E> {
/**
Expand Down