我想通过渠道来组织两个功能之间的通信。被叫方只能将数据发送到通道,而被叫方将在通道中等待数据select
。我想在被叫方签名中显示此限制。我想要的另一件事是使用通道的类型别名。例如,不是让chan string
我想使用MsgChan
定义为type MsgChan chan string
。我遇到了问题-如果取消注释行,下面的代码将无法编译test1(make(Ch))
:
package main
import "fmt"
type Ch chan int
type ChIn chan<- int
func test1(in ChIn) {
fmt.Println(in)
}
func test2(in chan<- int) {
fmt.Println(in)
}
func main() {
//test1(make(Ch))
test1(make(chan int))
test2(make(Ch))
test2(make(ChIn))
}
我不明白为什么我不能使用这种方法?
test1()
有一个类型的参数ChIn
。这是一个命名类型。您要传递一个类型的值,Ch
该值是双向通道类型,也是一个命名类型。
因此,为了对此进行编译,Ch
应该将type的值分配给ChIn
。语言规范不允许这样做。
引用可分配性(突出显示此处适用的那一项):
在以下任何一种情况下,都可以将值
x
分配给类型的变量T
(“x
可以分配给T
”):
如果尝试传递未命名类型但具有相同基础类型的值,则可以使其起作用,这可以通过使用类型转换来实现,例如:
test1((chan int)(make(Ch)))
但是上述转换将破坏具有命名Ch
类型的目的(因为您必须重复其类型文字才能将其转换为未命名类型,以便可以将其传递给test1()
)。
您应该做的是不要隐藏类型是通道(不要包含chan
在类型声明的类型文字中),而应为通道的元素类型创建一个新类型,例如:
type Msg int
func test(in chan<- Msg) {
fmt.Println(in)
}
func main() {
test(make(chan Msg))
test(make(chan<- Msg))
ch := make(chan Msg)
chIn := (chan<- Msg)(ch)
test(chIn)
}
在Go Playground上尝试一下。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句