Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use channel send direction in Go

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?

like image 599
softshipper Avatar asked Aug 05 '14 14:08

softshipper


People also ask

What are directional channels in Go language?

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.

How do I use a Go channel?

In Go language, a channel is created using chan keyword and it can only transfer data of the same type, different types of data are not allowed to transport from the same channel. You can also create a channel using make() function using a shorthand declaration.

Are channels passed by reference Golang?

Are channels implicitly passed by reference in go ? Yes, the reference types in Go are slice , map and channel .


1 Answers

Three issues:

  • You have the send and receive operations reversed (which is the error you're seeing)
  • Creating recv-only or send-only channels make no sense, as you cannot use them
  • 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)
}
like image 96
JimB Avatar answered Oct 14 '22 17:10

JimB