Reputation: 34081
In Go, it can be specified which direction a channel can send. I am trying to create an example about it, look at the following code:
package main
import (
"fmt"
"time"
)
func main() {
ic_send_only := make(<-chan int) //a channel that can only send data - arrow going out is sending
ic_recv_only := make(chan<- int) //a channel that can only receive a data - arrow going in is receiving
go func() {
ic_recv_only <- 4555
}()
go func() {
ic_send_only <- ic_recv_only
}()
fmt.Println(ic_recv_only)
time.Sleep(10000)
}
I get the compiler error
# command-line-arguments
.\send_receive.go:19: invalid operation: ic_send_only <- ic_recv_only (send to receive-only type <-chan int)
[Finished in 0.2s with exit code 2]
How can I use channel direction in the right way?
Or does anyone have a better sample than me?
Upvotes: 18
Views: 13971
Reputation: 10248
The key point that JimB has made, to summarise, is that
make
<-
. The ends are important.Note also that each end can be safely accessed concurrently by more than one goroutine.
Also note that JimB's example producer(i int, ch chan<- int)
and consumer(ch <-chan int)
functions have parameters that specify which end they use via <-chan
and chan<-
, instead of just chan
. Although this is optional, it is good practice because the compiler will help you fix silly mistakes if you do this.
Upvotes: 2
Reputation: 109404
Three issues:
The notation you're using is trying to send the channel itself, not the result. You need to receive and send, which requires two arrows.
ic_recv_only <- <-ic_send_only
You may be confused because you have the terminology reversed. <-ch
is a "receive operation", and ch <-
is a send operation. Note that in your example, everything would be deadlocked because you can't complete the corresponding sends and receives to pass something through either channel.
Here is a complete example:
// This receives an int from a channel. The channel is receive-only
func consumer(ch <-chan int) int {
return <-ch
}
// This sends an int over a channel. The channel is send-only
func producer(i int, ch chan<- int) {
ch <- i
}
func main() {
ch := make(chan int)
go producer(42, ch)
result := consumer(ch)
fmt.Println("received", result)
}
Upvotes: 28