<pre><code>func fanIn(inputs ...<-chan string) <-chan string {
c := make(chan string)
for cinput := inputs { // this line gives me error
go func() {for { c <- <-cinput}}()
}
}
</code></pre>
<p>It's pretty self explanatory on what I am trying to do but it seems go lang doens't like how i do it. Why?</p>
<hr/>**评论:**<br/><br/>dewey4iv: <pre><pre><code>func fanIn(inputs ...<-chan string) <-chan string {
c := make(chan string)
for _, in := range inputs { // this line gives me error
go func(ch <-chan string) {
for {
c <-ch
}
}(in)
}
}
</code></pre>
<p>You were missing the range keyword :).
I'd also like to point out that you don't have any way of signaling when a channel is done sending.</p></pre>binaryblade: <pre><p>I like how you attempted to avoid closing over the loop variable but didn't.</p></pre>dewey4iv: <pre><p>Yeah, haha - I was in the middle of editing it and lost internet connection. Thanks for paying attention though!</p></pre>juniorsysadmin1: <pre><p>Hmm i don't think it's doing what I want it to do. </p>
<p>I'm trying to write a variadic function of the following function. </p>
<pre><code>func fanIn(input1,input2 <-chan string) <-chan string{
c := make(chan string)
go func() {for { c <- <-input1}}()
go func() {for { c <- <-input2}}()
return c
}
</code></pre>
<p>So instead of 2 input it can take N inputs.</p>
<p>I then have the following function in my testcode</p>
<pre><code>func boring(msg string, s int) <-chan string { // this return a receive-only channel of strings
c := make(chan string)
go func() {
for i := 0; ; i++ {
c <- fmt.Sprintf("%s %d", msg, i)
time.Sleep(time.Second * time.Duration(s))
}
}()
return c // return the channel to th e caller
}
</code></pre>
<p>in main I have </p>
<pre><code>joe:= boring("joe", 1)
ann := boring("ann", 4)
bla := fanIn(joe, ann)
for i := 0; i < 5; i++ {
fmt.Println(<-bla)
}
</code></pre>
<p>Joe should appear 4 times and ann should appear once. The program end up having ann appear 5 times with 4 sec interval. </p>
<p>My code is in <a href="https://pastebin.com/PCqVvASU" rel="nofollow">pastebin</a></p></pre>dewey4iv: <pre><p>Take a look at the output here -- is this more what you are looking for?</p>
<p><a href="https://pastebin.com/Ti8fj7uY" rel="nofollow">https://pastebin.com/Ti8fj7uY</a></p></pre>juniorsysadmin1: <pre><p>yea that's what I was trying to achieve. </p></pre>dewey4iv: <pre><p>:thumbsup: </p></pre>mr-bosley: <pre><p>Surely this will memory leak, as the go routine inside...</p>
<pre><code>for _, in := range inputs { // this line gives me error
go func(ch <-chan string) {
for {
c <-ch
}
}(in)
}
</code></pre>
<p>will never stop?
There's a really good example of fan-in here.
<a href="https://blog.golang.org/pipelines" rel="nofollow">https://blog.golang.org/pipelines</a></p></pre>dewey4iv: <pre><blockquote>
<p>I'd also like to point out that you don't have any way of signaling when a channel is done sending.</p>
</blockquote>
<p>Oh completely! That's what I was getting at with the above. </p></pre>jerf: <pre><p>Missing "range" on the inputs.</p>
<p>While more complicated to work with, you may prefer either to use <a href="http://127.0.0.1:9000/pkg/reflect/#Select" rel="nofollow">reflect.Select</a> to do this all in one goroutine (as they may be <em>cheap</em> but they are not <em>free</em>), or conceivably, to try to make it so the destination channel is shared with the producers in a different way that prevents you from needing this. (Fan-in is a legitimate pattern, but it is not the first thing I'd reach for. You're usually better off trying to get the channels to the right places in the first place rather than building complicated networks in Go.)</p></pre>LimEJET: <pre><p>did you just try to link your local copy of the documentation</p></pre>jerf: <pre><p>Yes. Yes I did. What, you can't get to it? :)</p></pre>LimEJET: <pre><p>I guess that's shame on me for not having a local doc server up constantly.</p></pre>jammerlt: <pre><p>Inputs is a slice, so cinput ends up being the index in the slice, and not the channel. You are also missing the range keyword and a return value. So for _, cinput := range inputs</p></pre>binaryblade: <pre><p>Just a heads up that channels in an API appear very infrequently in the Stdlib.</p></pre>uncle_bad_touches: <pre><p>Look at <a href="https://golang.org/pkg/reflect/#Select" rel="nofollow">https://golang.org/pkg/reflect/#Select</a>. This would allow you to monitor all the channels in a single goroutine.</p></pre>ChristophBerger: <pre><p>In addition to all the helpful comments so far, let me mention <a href="https://blog.golang.org/pipelines" rel="nofollow">this blog post</a> from the Go blog that discusses fan-in and fan-out.</p></pre>disq: <pre><p>Copying from an example I did for a quickstart session:</p>
<pre><code>func copyData(in, out chan string) {
for { // infinite loop
out <- <-in // read from in, write to out
}
}
func fanIn(channels ...chan string) chan string {
out := make(chan string)
for _, ch := range channels { // iterate all params
go copyData(ch, out)
}
return out
}
</code></pre></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传