结构中的Golang通道:传递给函数时它是否可以是方向性的?

时间:2017-06-02 13:27:44

标签: go struct channel channels

将频道传递给某个功能时,我知道您可以指定频道可以使用该频道的方向;例如,

func MyFunc(ch chan<- string) {
    ch <- "Hello"
}

&#34; CH&#34;只能由MyFunc用于将字符串发送到其他地方的接收器,而MyFunc无法侦听来自ch的消息。

为了简化为一些goroutine创建动态数量的通道,我创建了一个包含通道的结构。

type ChanStruct struct {
    chMessages chan string
}

然后我实例化一个结构:

var slcChanStruct []ChanStruct
for a:= 0; a <=2; a++ {
    var tmpChanStruct ChanStruct
    tmpChanStruct.chMessages = make(chan string)
    slcChanStruct = append(slcChanStruct, tmpChanStruct)
}

现在我有3个结构,我可以通过在一片结构上进行单独读取/写入通道。但是当我把它们送到goroutines时:

for a:=0; a <=2; a++{
    go SomeFunc(slcChanStruct[a])
}

...有没有办法通过指定goroutine只能使用ChanStruct.ch频道发送来增加一些安全性?

注意我这样做的原因是,如果我不知道一组并行进程需要多少个通道(进程数作为命令行参数传递),请使用带通道的struct意味着我可以创建一个可以传递给任意数量的goroutine的切片,并通过它们的范围直接访问它们。之前,如果我想从多个goroutines中单独阅读,我必须创建一定数量的频道。我想通过指定进程只能以某种方式使用某个通道来增加一些安全性,就像我在使用单个通道时一样(单个通道意味着我可以做一些事情,比如告诉特定的goroutine在没有其他goroutine的情况下退出拦截它)。如果我不能使用结构中的通道为函数添加方向性,是否有更惯用的方法呢?

2 个答案:

答案 0 :(得分:1)

除了@Adrian的建议之外,如果你必须确保频道上的单向通信,你总是可以使用匿名功能:

for a:=0; a <=2; a++{
  go func f(ch <-string) {
    SomeFunc(ch)
  }(slcChanStruct[a].chMessages)
}

请注意,您必须将频道传递给SomeFunc而不是结构。

如果您仍希望在频道上执行双向通信,则可以重新将频道指定为单向类型:

type ChanStruct struct {
    chMessages chan string
}

type ChanStructRecv struct {
    chMessages <-chan string
}

// Update SomeFunc type:

func SomeFunc(s ChanStructRecv) {
  // ...
}

最后,可以类似地修改循环:

for a:=0; a <=2; a++{
  go func f(s ChanStruct) {
    var sr ChanStructRecv
    sr.chMessages = s.chMessages
    SomeFunc(sr)
  }(slcChanStruct[a])
}

答案 1 :(得分:0)

根据您的具体情况,有两种方式:

  • 传递频道而不是结构,并按照第一个示例
  • 制作频道参数方向
  • 不要直接暴露通道,只是暴露一个struct方法来写入它(如果没有方法可以从中读取它,它是有效的方向性的)
  • 使渠道结构成员具有方向性:

E.g。

type myStruct struct {
    c chan <- bool
}