Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I declare a slice of chan (channels) in func

Tags:

slice

go

channel

I'm trying to write function like this, but I can't declare slice of channels

func fanIn(set <-[]chan string) <-chan string {
    c := make(chan string)

    for i := range set {
        go func() { for {c <-set[i]} }()
    }
    return c
}

is it possible in Go to have a slice of channels as argument?

example of call

set := [2]chan string{mylib.Boring("Joe"), mylib.Boring("Ann")}
c := fanIn(set)

if I can do this

func fanIn(input1, input2 <-chan string) <-chan string {

I assume that it should be possible to have slice or array of "<-chan string"

updated:

func fanIn(set []<-chan string) <-chan string {
    c := make(chan string)

    for i := range set {
        go func() {
            for {
                x := <-set[i]
                c <- x
            }
        }()
    }

    return c
}

func main() {
    set := []<-chan string{mylib.Boring("Joe"), mylib.Boring("Ann"), mylib.Boring("Max")}
    c := fanIn(set)
    for i := 0; i < 10; i++ {
        fmt.Println(<-c)
    }
    fmt.Println("You're boring: I'm leaving.")
}
like image 386
qwertmax Avatar asked Sep 30 '22 16:09

qwertmax


1 Answers

I fixed the syntax in your function a bit, it compiles now:

func fanIn(set []<-chan string) <-chan string {
    c := make(chan string)


    for i := range set {
        // here is the main change - you receive from one channel and send to one.
        // the way you wrote it, you're sending the channel itself to the other channel
        go func() { for {c <- <- set[i]} }()
    }
    return c
}

BTW for the sake of readability, I'd write it as:

    go func() {
        for {
            x := <-set[i]
            c <- x
        }
    }()

EDIT: Your original code had the problem of using set[i] inside the goroutine, causing them all to read from the last channel. here's a fixed version:

func fanIn(set []<-chan string) <-chan string {
    c := make(chan string)

    for i := range set {
        go func(in <-chan string) {
            for {
                x := <- in
                c <- x
            }
        }(set[i])
    }
    return c
}
like image 74
Not_a_Golfer Avatar answered Oct 03 '22 01:10

Not_a_Golfer