Skip to content
Kavachकवच

Channels: put and take

● Advanced3 min

take() gives the next value as Taken.Item(value), or Taken.Closed once the channel is closed and empty.

fn main() {
    const (send, receive) = Channel<String>(capacity: 2)
    send.put("first")
    send.close()
    for _ in 1..=2 {
        match receive.take() {
            Taken.Item(text) => print("took {text}"),
            Taken.Closed => print("closed: nothing more will come"),
        }
    }
}

The program ran and printed:

kavach run take.kav

took firstclosed: nothing more will come
take.kav: Kavach code, then what running it prints

Taken<T> = Item(value: T) | Closed keeps a value and the channel's end apart, even when the values are optional. A Channel<Int?> can carry none, and none taken is Item(value: none), not Closed:

fn main() {
    const (send, receive) = Channel<Int?>(capacity: 3)
    send.put(7)
    send.put(none)
    send.close()
    print(receive.take())
    print(receive.take())
    print(receive.take())
}

The program ran and printed:

kavach run take-none.kav

Item(value: 7)Item(value: none)Closed
take-none.kav: Kavach code, then what running it prints
  • for v in receive takes values until take() gives Closed.
  • Putting into a closed channel is a bug, so it panics, as does putting into one whose receivers are all gone.