谁能解释<-done关闭后将执行的执行

时间:2019-07-17 12:27:30

标签: go

我无法理解该程序for select,因此我需要帮助来解释该程序的顺序,

    done := make(chan interface{})
    go func() {
        time.Sleep(5 * time.Second)
        close(done)
    }()
    workcount := 0
loop:
    for {
        select {
        case <-done:
            break loop
        default:
        }
        workcount++
        fmt.Println(workcount)
        time.Sleep(1 * time.Second)
    }
    fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)

1 个答案:

答案 0 :(得分:0)

    // Our communication channel is created
    done := make(chan interface{})

    // run this function as goroutine
    go func() {
        // wait/sleep 5 seconds
        time.Sleep(5 * time.Second)

        // close our communication channel
        close(done)
    }()

    // initialize workcount with 0
    workcount := 0

loop:
    // loop
    for {
        // read channel data
        select {
        // if channel is closed break this loop, break = stop!
        case <-done:
            break loop

        // default do nothing
        default:
        }

        // if our channel doesn't send anything, just add +1 to workcount
        workcount++

        // print workcount
        fmt.Println(workcount)

        // wait 1 second before we run this loop again
        time.Sleep(1 * time.Second)
    }

    // so workcount is 5, cuz our goroutine will send term signal after 5 seconds
    fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)

解决此问题的更干净的方法是

package main

import (
    "fmt"
    "time"
)

func main() {
    // sends after 5 seconds to this channel https://golang.org/pkg/time/#After
    timeout := time.After(5 * time.Second)

    // sends each second to this channel https://golang.org/pkg/time/#Tick
    tick := time.Tick(1 * time.Second)

    // our workcount var
    workcount := 0

    // for infinite
    for {
        // waits for data on each channel
        select {
        // fired if time.After wrote in timeout
        case <-timeout:
            fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)
            return
        // fired if time.Tick wrote in tick
        case <-tick:
            workcount++
            fmt.Println(workcount)
        }
    }
}

您在main函数中运行代码,因此我们需要返回。我们将使用return修复此代码

package main

import (
    "fmt"
    "time"
)

func main() {
    // Our communication channel is created
    done := make(chan interface{})

    // run this function as goroutine
    go func() {
        // wait/sleep 5 seconds
        time.Sleep(5 * time.Second)

        // close our communication channel
        close(done)
    }()

    // initialize workcount with 0
    workcount := 0

    // loop
    for {
        // read channel data
        select {
        // if channel is closed break this loop, break = stop!
        case <-done:
            fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)
            return

        // default do nothing
        default:
        }

        // if our channel doesn't send anything, just add +1 to workcount
        workcount++

        // print workcount
        fmt.Println(workcount)

        // wait 1 second before we run this loop again
        time.Sleep(1 * time.Second)
    }
}