anonymous struct and empty struct

后端 未结 5 1995
猫巷女王i
猫巷女王i 2020-12-02 09:31

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

package main

import \"fmt\"

var battle = make(chan string)

func warrior(name string, done chan struct{}) {
    select          


        
5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-02 09:56

    done channel is used to receive notifications from warrior method that indicates the worker is done processing. So the channel can be anything, for example:

    func warrior(name string, done chan bool) {
        select {
        case opponent := <-battle:
            fmt.Printf("%s beat %s\n", name, opponent)
        case battle <- name:
            // I lost :-(
        }
        done <- true
    }
    
    func main() {
        done := make(chan bool)
        langs := []string{"Go", "C", "C++", "Java", "Perl", "Python"}
        for _, l := range langs { go warrior(l, done) }
        for _ = range langs { <-done }
    }
    

    We declare done := make(chan bool) as a channel that receives bool value, and send true at the end of warrior instead. This works! You can also define the done channel to any other type, it won't matter.

    1. So what is with the weird done <- struct{}{}?

    It is just another type that will be passed to channel. This is an empty struct, if you are familiar with the following:

    type User struct {
        Name string
        Email string
    }
    

    struct{} makes no difference except it contains no fields, and struct{}{} is just an instance out of it. The best feature is it does not cost memory space!

    2. for loop usage

    We create 6 goroutines to run in the background with this line:

        for _, l := range langs { go warrior(l, done) }
    

    We use the for _ = range langs { <-done }, because the main goroutine(where main function runs) does not wait for goroutins to finish.

    If we does not include the last for line, chances are we see no outputs(because main goroutines quits before any child goroutines executes fmt.Printf code, and when main goroutine quits, all child goroutines will quit with it, and will not have any chance to run anyway).

    So we wait for all goroutines to finish(it runs to the end, and send a message to the done channel), then exits. done channel here is a blocked channel, which means <-done will block here until a message is received from the channel.

    We have 6 goroutines in the background, and use for loop, we wait until all goroutines send a message which means it finished running(because the done <-struct{}{} is at the the end of function).

提交回复
热议问题