我正在使用带标签的无限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")
}
答案 0 :(得分:4)
建立信号通道。
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
}
}()
读取封闭通道立即返回零值(但在这种情况下我们不需要它)。否则从中读取块并选择将执行传递给&#34;默认&#34;情况下。
myLoop:
for {
select {
case <- quit:
break myLoop
default:
fmt.Println("iteration", i)
i++
}
}
答案 1 :(得分:4)
Darigaaz的答案适用于单个goroutine,但关闭一个封闭的频道恐慌(并且在该实例中你也不需要等待组)。如果你有多个goroutine,并希望循环在所有循环完成后退出,请使用一个具有更近程序的waitgroup:
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中断:
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
}