当goroutine产生相同的goroutine时,会启动3个不同的funcs(显然会忽略参数)

For 3 different and distinct "c"

for _, c := range u.components { // u.components has 3 members
    fmt.Printf("%v %v", c.name, c.channel) // prints 3 distinct name/channel pairs 
    go c.Listen(); // a method of c that listens on channel c.channel
}

...launches 3 identical goroutines in which c.name and c.channel are identical.

The long version (commented, short code): https://play.golang.org/p/mMQb_5jLjm

This is my first Go program, I'm sure I'm missing something obvious. Any ideas?

Thank you.

The call to c.Listen() is closing around the value of c, which is passed via a pointer to Listen, and each iteration changes that value. It's easier to visualize if you look at the method call as a method expression

go (*component).Listen(&c)

https://golang.org/doc/faq#closures_and_goroutines

Create a new value for c on each iteration to prevent the previous from being overwritten:

for _, c := range u.components { // u.components has 3 members
    c := c
    fmt.Printf("%v %v", c.name, c.channel) // prints 3 distinct name/channel pairs 
    go c.Listen(); // a method of c that listens on channel c.channel
}

Or use the value contained in the slice directly:

for i := range u.components {
    go u.components[i].Listen()
}