为什么通道的通道方向变化不兼容?

pep*_*ico 6 channel go

我喜欢尽可能限制地提供接口,以避免错误使用,以便明确和自我记录.

因此,我希望在用户单向使用时提供定向通道,但当然,我在内部有一个双向通道副本.

以下作品的分配:

var internal chan int
var external <-chan int
external = internal
Run Code Online (Sandbox Code Playgroud)

但是现在我想向用户提供一个<-chan chan<- int类型(在函数的返回中),但是以下内容不起作用:

var internal chan chan int
var external <-chan chan<- int
external = internal // this fails
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  • 究竟为什么这不起作用?
  • 所以,我可以声明一个<-chan chan<-类型的变量,但是...在任何实际意义上都不能使用这样的类型?(因为即使有方向性通道,它们也是在双向编排中使用的AFAIK,并且因为无法进行分配,所以不能以这种方式使用它们)

nem*_*emo 4

这不起作用的原因

规范中关于通道可分配性的规定如下:

[通道]值x可分配给类型的变量T(“x可分配给T”)[当]x是双向通道值,T是通道类型,x的类型V并且T具有相同的元素类型,并且至少之一VT不是命名类型。

这准确地反映了您所经历的情况:

  • chan (chan int)<- chan (chan int)工作
  • chan (chan int)<- chan (chan<- int)

其原因是元素类型(chan关键字后面的元素类型)不相等。

我可以声明它但不能使用它吗?

可以使用它,但不能按照您想要的方式使用。不可能按照您的方式分配变量,但通过更正元素类型,您确实可以使用它:

var internal chan chan<- int
var external <-chan chan<- int
external = internal
Run Code Online (Sandbox Code Playgroud)

如果您只有chan chan int类型,则需要复制您的值(播放示例):

var internal chan chan int
var internalCopy chan chan<- int

go func() { for e := range internal { internalCopy <- e } }()

var external <-chan chan<- int
external = internalCopy
Run Code Online (Sandbox Code Playgroud)