Search code examples
concurrencygochannelgoroutine

anonymous struct and empty struct


http://play.golang.org/p/vhaKi5uVmm

package main

import "fmt"

var battle = make(chan string)

func warrior(name string, done chan struct{}) {
    select {
    case opponent := <-battle:
        fmt.Printf("%s beat %s\n", name, opponent)
    case battle <- name:
        // I lost :-(
    }
    done <- struct{}{}
}

func main() {
    done := make(chan struct{})
    langs := []string{"Go", "C", "C++", "Java", "Perl", "Python"}
    for _, l := range langs { go warrior(l, done) }
    for _ = range langs { <-done }
}

[1st Question]

 done <- struct{}{}

How and Why do we need this weird-looking struct? Is it empty struct or anonymous struct? I googled it but couldn't find the right answer or documentation to explain about this.

The original source is from Andrew Gerrand's talk http://nf.wh3rd.net/10things/#10

Here

 make(chan struct{})

done is a channel of type struct{}

So I tried with

 done <- struct{}

But it is not working. Why do I need an extra brackets for this line?

 done <- struct{}{}

[2nd Question]

 for _ = range langs { <-done }

Why do I need this line? I know that this line is necessary because without this line, no output. But Why and what does this line do? And what makes it necessary in this code? I know that <-done is to receive values from the channel done and discard the received values. But why do I need to do this?


Solution

  • Composite literals

    Composite literals construct values for structs, arrays, slices, and maps and create a new value each time they are evaluated. They consist of the type of the value followed by a brace-bound list of composite elements. An element may be a single expression or a key-value pair.

    struct{}{} is a composite literal of type struct{}, the type of the value followed by a brace-bound list of composite elements.

    for _ = range langs { <-done } is waiting until all the goroutines for all the langs have sent done messages.