duanqin7791 2017-06-28 22:36
浏览 94
已采纳

动态创建通道以用作Go中可变参数函数的参数

Is it possible to dynamically create a channel in Go and then assign it a value? This fan-out-fan-in code works with

f1 := factorial(in)
f2 := factorial(in)
for n := range merge(f1, f2) { 
        fmt.Println(n)
}

But I'd like to do something like

var res [2]<-chan int
res[0] = make(chan int)
res[0] = factorial(in)
res[1] = make(chan int)
res[1] = factorial(in)
for n := range merge(res...)
    fmt.Println(n)
}

This gives the following error

$ go run main.go
# command-line-arguments
.\main.go:26: cannot use res (type [2]<-chan int) as type []<-chan int in 
argument to merge

Here is the full code...

package main

import (
    "fmt"
    "sync"
)

func main() {

    in := gen()

    f1 := factorial(in) // code to be replaced
    f2 := factorial(in) // code to be replaced
    for n := range merge(f1, f2) { // code to be replaced
        fmt.Println(n) // code to be replaced
    } // code to be replaced

    // What I'd like to use instead of the above...
    //var res [2]<-chan int
    //res[0] = make(chan int)
    //res[0] = factorial(in)
    //res[1] = make(chan int)
    //res[1] = factorial(in)
    // for n := range merge(res...)
    //  fmt.Println(n)
    //}
    // This commented code generates the following error
    //$ go run main.go
    //# command-line-arguments
    //.\main.go:20: cannot use res (type [2]<-chan int) as type []<-chan int in argument to merge

}

func gen() <-chan int {
    out := make(chan int)
    go func() {
        for i := 0; i < 100; i++ {
            for j := 3; j < 13; j++ {
                out <- j
            }
        }
        close(out)
    }()
    return out
}

func factorial(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        for n := range in {
            out <- fact(n)
        }
        close(out)
    }()
    return out
}

func fact(n int) int {
    total := 1
    for i := n; i > 0; i-- {
        total *= i
    }
    return total
}

func merge(cs ...<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    wg.Add(len(cs))
    for _, c := range cs {
        go func(ch <-chan int) {
            for n := range ch {
                out <- n
            }
            wg.Done()
        }(c)
    }
    go func() {
        wg.Wait()
        close(out)
    }()
    return out
}
  • 写回答

2条回答 默认 最新

  • doureng1083 2017-06-28 23:09
    关注

    You have two problems:

    1. A variadic function takes multiple args (fmt.Println, for example, takes multiple interface{}). You're sending an array.

    2. An array which is size [2] is not the same as size [] (yes, size of array is part of the type in go).

    What you want is something like:

        for n := range merge(res[:]) {
    

    ...

    func merge(cs []<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    wg.Add(len(cs))
    for _, c := range cs {
        go func(ch <-chan int) {
            for n := range ch {
                out <- n
            }
            wg.Done()
        }(c)
    }
    go func() {
        wg.Wait()
        close(out)
    }()
    return out
    

    }

    https://play.golang.org/p/zTrrsRkKJV

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题