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 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?