Golang:如何从循环外停止执行 for 循环?

我正在使用带有标签的无限 for 循环。在 for 循环的范围之外,我有一个计划函数作为 go 例程运行。当满足某个条件时,我想从预定函数中中断 for 循环。我怎样才能做到这一点?这就是我正在尝试的,由于范围问题,这显然不起作用。


package main


import (

  "fmt"

  "time"

  "sync"

)


func main() {

  count := 0

  var wg sync.WaitGroup

  wg.Add(1)

  t := time.NewTicker(time.Second*1)


  go func (){

    for {

        fmt.Println("I will print every second", count)

        count++ 

        if count > 5 {

          break myLoop;

          wg.Done()

        }

        <-t.C

    }  

  }()


  i := 1


  myLoop:

  for {

    fmt.Println("iteration", i)

    i++

  }


  wg.Wait()

  fmt.Println("I will execute at the end")


}


慕丝7291255
浏览 460回答 2
2回答

弑天下

建立一个信号通道。quit := make(chan struct{}{})当你想打破循环时关闭它。go func (){&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("I will print every second", count)&nbsp; &nbsp; &nbsp; &nbsp; count++&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if count > 5 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close(quit)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; <-t.C&nbsp; &nbsp; }&nbsp;&nbsp;&nbsp; }()在关闭的通道上读取立即返回零值(但在这种情况下我们不需要它)。否则从中读取会阻塞并选择将执行传递到“默认”情况。&nbsp;myLoop:&nbsp; for {&nbsp; &nbsp; select {&nbsp; &nbsp; case <- quit:&nbsp; &nbsp; &nbsp; break myLoop&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; fmt.Println("iteration", i)&nbsp; &nbsp; &nbsp; i++&nbsp; &nbsp; }&nbsp; }

Smart猫小萌

Darigaaz 的答案适用于单个 goroutine,但关闭关闭的通道会出现恐慌(在这种情况下您也不需要等待组)。如果您有多个 goroutine,并且希望循环在所有这些都完成后退出,请使用具有更接近例程的等待组:https://play.golang.org/p/RhmUzWhneTpackage mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; quitCh := make(chan struct{})&nbsp; &nbsp; for i := 1; i <= 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count := 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t := time.NewTicker(time.Millisecond)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for count <= 5 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Goroutine %v iteration %v\n", i, count)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count++&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <-t.C&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; }&nbsp; &nbsp; // This is the closer routine.&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(quitCh)&nbsp; &nbsp; }()&nbsp; &nbsp; t := time.NewTicker(500 * time.Microsecond)loop:&nbsp; &nbsp; for i := 1; ; i++ { // this is still infinite&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-quitCh:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break loop // has to be named, because "break" applies to the select otherwise&nbsp; &nbsp; &nbsp; &nbsp; case <-t.C:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Main iteration", i)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("End!")}作为命名循环样式的替代方案,您可以在该选择中使用fallthrough break:&nbsp; &nbsp; for i := 1; ; i++ { // this is still infinite&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-quitCh:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // fallthrough&nbsp; &nbsp; &nbsp; &nbsp; case <-t.C:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Main iteration", i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; break // only reached if the quitCh case happens&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go