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++
}
}

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
}
- 2 回答
- 0 关注
- 459 浏览
添加回答
举报