为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕丝7291255 2022-01-17 17:05:45
我正在使用带有标签的无限 for 循环。在 for 循环的范围之外,我有一个计划函数作为 go 例程运行。当满足某个条件时,我想从预定函数中中断 for 循环。我怎样才能做到这一点?这就是我正在尝试的,由于范围问题,这显然不起作用。package mainimport (  "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")}
查看完整描述

2 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

建立一个信号通道。


quit := make(chan struct{}{})

当你想打破循环时关闭它。


go func (){

    for {

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

        count++ 

        if count > 5 {

          close(quit)

          wg.Done()

          return

        }

        <-t.C

    }  

  }()

在关闭的通道上读取立即返回零值(但在这种情况下我们不需要它)。否则从中读取会阻塞并选择将执行传递到“默认”情况。


 myLoop:

  for {

    select {

    case <- quit:

      break myLoop

    default:

      fmt.Println("iteration", i)

      i++

    }

  }


查看完整回答
反对 回复 2022-01-17
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

Darigaaz 的答案适用于单个 goroutine,但关闭关闭的通道会出现恐慌(在这种情况下您也不需要等待组)。如果您有多个 goroutine,并且希望循环在所有这些都完成后退出,请使用具有更接近例程的等待组:


https://play.golang.org/p/RhmUzWhneT


package main


import (

    "fmt"

    "sync"

    "time"

)


func main() {

    var wg sync.WaitGroup

    quitCh := make(chan struct{})


    for i := 1; i <= 5; i++ {

        wg.Add(1)

        go func(i int) {

            count := 1

            t := time.NewTicker(time.Millisecond)

            for count <= 5 {

                fmt.Printf("Goroutine %v iteration %v\n", i, count)

                count++

                <-t.C

            }

            wg.Done()

        }(i)

    }


    // This is the closer routine.

    go func() {

        wg.Wait()

        close(quitCh)

    }()


    t := time.NewTicker(500 * time.Microsecond)

loop:

    for i := 1; ; i++ { // this is still infinite

        select {

        case <-quitCh:

            break loop // has to be named, because "break" applies to the select otherwise

        case <-t.C:

            fmt.Println("Main iteration", i)

        }

    }

    fmt.Println("End!")


}

作为命名循环样式的替代方案,您可以在该选择中使用fallthrough break:


    for i := 1; ; i++ { // this is still infinite

        select {

        case <-quitCh:

            // fallthrough

        case <-t.C:

            fmt.Println("Main iteration", i)

            continue

        }

        break // only reached if the quitCh case happens

    }


查看完整回答
反对 回复 2022-01-17
  • 2 回答
  • 0 关注
  • 459 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号