谁能解释一下 <-done 将在 close [close] 后运行的执行

我无法理解这个程序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)


蛊毒传说
浏览 132回答 1
1回答

慕尼黑5688855

// Our communication channel is created&nbsp; &nbsp; done := make(chan interface{})&nbsp; &nbsp; // run this function as goroutine&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; // wait/sleep 5 seconds&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(5 * time.Second)&nbsp; &nbsp; &nbsp; &nbsp; // close our communication channel&nbsp; &nbsp; &nbsp; &nbsp; close(done)&nbsp; &nbsp; }()&nbsp; &nbsp; // initialize workcount with 0&nbsp; &nbsp; workcount := 0loop:&nbsp; &nbsp; // loop&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; // read channel data&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; // if channel is closed break this loop, break = stop!&nbsp; &nbsp; &nbsp; &nbsp; case <-done:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break loop&nbsp; &nbsp; &nbsp; &nbsp; // default do nothing&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // if our channel doesn't send anything, just add +1 to workcount&nbsp; &nbsp; &nbsp; &nbsp; workcount++&nbsp; &nbsp; &nbsp; &nbsp; // print workcount&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(workcount)&nbsp; &nbsp; &nbsp; &nbsp; // wait 1 second before we run this loop again&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(1 * time.Second)&nbsp; &nbsp; }&nbsp; &nbsp; // so workcount is 5, cuz our goroutine will send term signal after 5 seconds&nbsp; &nbsp; fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)解决这个问题的一个更干净的方法是package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; // sends after 5 seconds to this channel https://golang.org/pkg/time/#After&nbsp; &nbsp; timeout := time.After(5 * time.Second)&nbsp; &nbsp; // sends each second to this channel https://golang.org/pkg/time/#Tick&nbsp; &nbsp; tick := time.Tick(1 * time.Second)&nbsp; &nbsp; // our workcount var&nbsp; &nbsp; workcount := 0&nbsp; &nbsp; // for infinite&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; // waits for data on each channel&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; // fired if time.After wrote in timeout&nbsp; &nbsp; &nbsp; &nbsp; case <-timeout:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; // fired if time.Tick wrote in tick&nbsp; &nbsp; &nbsp; &nbsp; case <-tick:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; workcount++&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(workcount)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}您在主函数中运行代码,因此我们需要返回。我们将使用 return 修复此代码package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; // Our communication channel is created&nbsp; &nbsp; done := make(chan interface{})&nbsp; &nbsp; // run this function as goroutine&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; // wait/sleep 5 seconds&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(5 * time.Second)&nbsp; &nbsp; &nbsp; &nbsp; // close our communication channel&nbsp; &nbsp; &nbsp; &nbsp; close(done)&nbsp; &nbsp; }()&nbsp; &nbsp; // initialize workcount with 0&nbsp; &nbsp; workcount := 0&nbsp; &nbsp; // loop&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; // read channel data&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; // if channel is closed break this loop, break = stop!&nbsp; &nbsp; &nbsp; &nbsp; case <-done:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Achieved %v cycles of work before signalled to stop \n", workcount)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; // default do nothing&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // if our channel doesn't send anything, just add +1 to workcount&nbsp; &nbsp; &nbsp; &nbsp; workcount++&nbsp; &nbsp; &nbsp; &nbsp; // print workcount&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(workcount)&nbsp; &nbsp; &nbsp; &nbsp; // wait 1 second before we run this loop again&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(1 * time.Second)&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go