Go中的通道类型别名很奇怪

时间:2016-04-24 08:00:26

标签: go compiler-errors alias channel

我想通过渠道组织两个功能之间的通信。被叫方只能向通道发送数据,而主叫方将在select中等待它。我想在被调用者签名中显示这种限制。我想要的另一件事是使用通道的类型别名。例如,我没有chan string而是希望使用定义为MsgChan的{​​{1}}。我遇到了问题 - 如果取消注释行type MsgChan chan string

,下面的代码将无法编译
test1(make(Ch))

我不明白为什么我不能使用这种方法?

1 个答案:

答案 0 :(得分:3)

test1()有一个ChIn类型的参数。这是一种命名类型。您希望传递类型为Ch的值,这是一种双向通道类型,也是一种命名类型。

因此,为了编译它,Ch的值应该可以分配给ChIn类型。语言规范不允许这样做。

引用Assignability(突出显示适用于此处的内容):

  

x可分配给T类型的variable(“x可分配给T”)在以下任何一种情况下:< / p>      

      
  • x的类型与T相同。
  •   
  • x的类型VT具有相同的underlying typesVT中至少有一个不是命名类型
  •   
  • T是一种界面类型,x implements T
  •   
  • x是双向渠道值,T是渠道类型,x的类型VT具有相同的元素类型,VT中至少有一个不是命名类型。
  •   
  • x是预先声明的标识符nilT是指针,函数,切片,地图,通道或接口类型。
  •   
  • x是一种无类型的constant,可以使用T类型的值表示。
  •   

如果您尝试传递未命名类型的值但具有相同的基础类型,则可以使其工作,这可以通过使用类型转换来实现,例如:

test1((chan int)(make(Ch)))

但是上述转换会破坏具有命名Ch类型的目的(因为您必须重复其类型文字才能将其转换为未命名的类型,以便您可以将其传递给{{1} })。

你应该做的是不要隐藏类型是一个通道(不要在类型声明的类型文字中包含test1()),只为通道的元素类型创建一个新类型,例如:

chan

Go Playground上尝试。