如何在Go中使用频道发送方向

时间:2014-08-05 14:29:00

标签: multithreading go

在Go中,可以指定通道可以发送的方向。我正在尝试创建一个关于它的示例,请查看以下代码:

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)

}

我收到编译错误

# 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]

如何以正确的方式使用频道指示?

或者有人比我有更好的样本吗?

2 个答案:

答案 0 :(得分:10)

三个问题:

  • 您的发送和接收操作已逆转(这是您看到的错误)
  • 创建仅限recv或仅发送通道毫无意义,因为您无法使用它们
  • 您使用的符号是尝试发送频道本身,而不是结果。您需要接收发送,这需要两个箭头。

    ic_recv_only <- <-ic_send_only

您可能会感到困惑,因为您的术语已被颠倒过来。 <-ch是“接收操作”,ch <-是发送操作。请注意,在您的示例中,所有内容都将处于死锁状态,因为您无法完成相应的发送和接收以通过任一通道传递内容。

这是一个完整的例子:

// 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)
}

答案 1 :(得分:0)

JimB总结的关键点是

  • 您使用make
  • 创建频道
  • 每个频道都有两个结尾
  • 您通过<-通过结束渠道进行沟通。目的很重要。
  • 发送端接收端;通道是单向的。

另请注意,可以通过多个goroutine安全地同时访问每一端。

另请注意,JimB的示例producer(i int, ch chan<- int)consumer(ch <-chan int)函数具有参数,用于指定他们通过<-chanchan<-使用哪一端,而不仅仅是{{ 1}}。虽然这是可选的,但它是良好做法,因为如果你这样做,编译器将帮助你解决愚蠢的错误。