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 關注
- 489 瀏覽
添加回答
舉報