I'm learning Go and so far very impressed with it. I've read all the online docs at golang.org and am halfway through Chrisnall's "The Go Programming Language Phrasebook". I get the concept of channels and think that they will be extremely useful. However, I must have missed something important along the way, as I can't see the point to one-way channels.
If I'm interpreting them correctly, a read-only channel can only be received on and a write-only channel can only be transmitted on, so why have a channel that you can send to and never receive on? Can they be cast from one "direction" to the other? If so, again, what's the point if there's no actual constraint? Are they nothing more than a hint to client code of the channel's purpose?
So, what are the channels in Golang exactly? Channels are the medium through which goroutines can communicate with each other. In simple terms, a channel is a pipe that allows a goroutine to either put or read the data.
This means channels can start out bidirectional, but magically become directional simply by assigning a regular channel to a variable of a constrained type. This is very useful for creating receive-only channels that no one can close but you.
Buffered channels in Go are always FIFO. The specification clearly says: Channels act as first-in-first-out queues. If the values coming out of the channel are not FIFO, then this is a bug in the channel implementation.
Channel operation (i.e. write or read) are blocking in nature. This means: When we send data into the channel using a GoRoutine, it will be blocked until the data is consumed by another GoRoutine. When we receive data from channel using a GoRoutine, it will be blocked until the data is available in the channel.
A channel can be made read-only to whoever receives it, while the sender still has a two-way channel to which they can write. For example:
func F() <-chan int { // Create a regular, two-way channel. c := make(chan int) go func() { defer close(c) // Do stuff c <- 123 }() // Returning it, implicitely converts it to read-only, // as per the function return value. return c }
Whoever calls F()
, receives a channel from which they can only read. This is mostly useful to avoid potential misuse of a channel at compile time. Because read/write-only channels are distinct types, the compiler can use its existing type-checking mechanisms to ensure the caller does not try to write stuff into a channel it has no business writing to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With