dousi0144 2017-06-02 13:27
浏览 72
已采纳

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

When passing a channel to a function, I know you can specify the direction that channel may use the channel for; for example,

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

"ch" can only be used by MyFunc to send strings to a receiver elsewhere and MyFunc cannot listen for messages from ch.

To simplify creating a dynamic number of channels to some number of goroutines, I created a struct containing channels.

type ChanStruct struct {
    chMessages chan string
}

Then I instantiate a structs:

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

Now I have 3 structs I can individually read/write with a channel by ranging over a slice of structs. But when I send them off to goroutines:

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

...is there a way to add a bit of safety by specifying that the goroutines can only, for example, send using the ChanStruct.ch channel?

NOTE the reason I was doing this is that if I don't know how many channels I'll need for a parallel set of processes (the number of processes are passed as a command line argument) using a struct with channels means I can create a slice that can be passed to any number of goroutines and directly access them individually by ranging over them; before, I had to create a set number of channels if I wanted to individually read from a number of goroutines. I'd like to add some safety to this by specifying that processes can only use a channel a certain way, like I could when using individual channels (individual channels mean I can do something like telling a particular goroutine to quit without other goroutines intercepting it). Is there a more idiomatic way to do this if I can't add directionality to functions using the channel in a struct?

  • 写回答

2条回答 默认 最新

  • 普通网友 2017-06-02 13:49
    关注

    On top of @Adrian's suggestions, if you have to ensure one way communication on a channel, you can always use an anonymous function:

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

    Note that you'll have to pass the channel to SomeFunc instead of the struct.

    If you still want to perform both way communication on your channel, you can re assign the channel to a one directional type:

    type ChanStruct struct {
        chMessages chan string
    }
    
    type ChanStructRecv struct {
        chMessages <-chan string
    }
    
    // Update SomeFunc type:
    
    func SomeFunc(s ChanStructRecv) {
      // ...
    }
    

    Finally, the loop can be modified similarly:

    for a:=0; a <=2; a++{
      go func f(s ChanStruct) {
        var sr ChanStructRecv
        sr.chMessages = s.chMessages
        SomeFunc(sr)
      }(slcChanStruct[a])
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘