How can I use channel send direction in Go

huangapple go评论82阅读模式
英文:

How can I use channel send direction in Go

问题

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

package main

import (
	"fmt"
	"time"
)

func main() {

	ic_send_only := make(<-chan int) // 只能发送数据的通道 - 箭头指向外部表示发送
	ic_recv_only := make(chan<- int) // 只能接收数据的通道 - 箭头指向内部表示接收

	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]

我应该如何正确使用通道方向?

还是有其他人有比我更好的示例吗?

英文:

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 (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {

	ic_send_only := make(&lt;-chan int) //a channel that can only send data - arrow going out is sending
	ic_recv_only := make(chan&lt;- int) //a channel that can only receive a data - arrow going in is receiving

	go func() {
		ic_recv_only &lt;- 4555
	}()

	go func() {

		ic_send_only &lt;- 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 &lt;- ic_recv_only (send to receive-only type &lt;-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?

答案1

得分: 27

三个问题:

  • 你把发送和接收操作颠倒了(这就是你看到的错误)
  • 创建只接收或只发送的通道没有意义,因为你不能使用它们
  • 你使用的符号尝试发送通道本身,而不是结果。你需要接收 并且 发送,这需要两个箭头。

ic_recv_only <- <-ic_send_only

你可能会因为术语颠倒而感到困惑。<-ch 是一个“接收操作”,而 ch <- 是一个发送操作。请注意,在你的示例中,由于你无法完成相应的发送和接收来通过任何一个通道传递数据,所以一切都会陷入僵局。

这是一个完整的示例:

// 这从通道接收一个整数。通道是只接收的
func consumer(ch <-chan int) int {
return <-ch
}

// 这通过通道发送一个整数。通道是只发送的
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)
}

英文:

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 &lt;- &lt;-ic_send_only

You may be confused because you have the terminology reversed. &lt;-ch is a "receive operation", and ch &lt;- 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 &lt;-chan int) int {
	return &lt;-ch
}

// This sends an int over a channel. The channel is send-only
func producer(i int, ch chan&lt;- int) {
	ch &lt;- i
}

func main() {
	ch := make(chan int)
	go producer(42, ch)
	result := consumer(ch)
	fmt.Println(&quot;received&quot;, result)
}

答案2

得分: 1

JimB所提出的关键点总结如下:

  • 使用make创建通道
  • 每个通道都有两个端点
  • 通过通道的端点进行通信,使用<-操作符。端点非常重要。
  • 通道有一个发送端和一个接收端,通道是单向的。

还要注意,每个端点可以被多个goroutine同时安全地访问。

此外,还要注意JimB的示例中,producer(i int, ch chan<- int)consumer(ch <-chan int)函数的参数通过<-chanchan<-指定了它们使用的端点,而不仅仅是chan。虽然这是可选的,但这是良好的实践,因为如果你这样做,编译器将帮助你修复愚蠢的错误。

英文:

The key point that JimB has made, to summarise, is that

  • You create channels using make
  • Every channel has two ends.
  • You communicate via the ends of channels via &lt;-. The ends are important.
  • There is a sending end and a receiving end; channels are unidirectional.

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&lt;- int) and consumer(ch &lt;-chan int) functions have parameters that specify which end they use via &lt;-chan and chan&lt;-, 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.

huangapple
  • 本文由 发表于 2014年8月5日 22:28:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/25141337.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定