1 回答

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊
Waitgroup 在此代碼中是多余的。執(zhí)行與等待通道結(jié)果的循環(huán)完美同步。在所有功能完成工作并從通道讀取發(fā)布的結(jié)果之前,代碼不會(huì)向前移動(dòng)。僅當(dāng)您的函數(shù)需要在結(jié)果發(fā)布到通道后執(zhí)行任何工作時(shí)才需要 Waitgroup。
我也更喜歡稍微不同的實(shí)現(xiàn)。在發(fā)布的實(shí)現(xiàn)中,我們不會(huì)在每次執(zhí)行函數(shù)時(shí)將結(jié)果和錯(cuò)誤都發(fā)送到通道中。相反,我們可以只發(fā)送成功執(zhí)行的結(jié)果,并在代碼失敗時(shí)只發(fā)送錯(cuò)誤。
優(yōu)點(diǎn)是簡(jiǎn)化了結(jié)果/錯(cuò)誤處理。我們?cè)跊](méi)有nils.
在這個(gè)例子中,函數(shù)返回一個(gè)數(shù)字,我們發(fā)送它的默認(rèn)值0以防出錯(cuò)。如果零可能是合法的函數(shù)執(zhí)行結(jié)果,則從成功中過(guò)濾出不成功的執(zhí)行結(jié)果可能會(huì)很復(fù)雜。
與錯(cuò)誤相同。要檢查我們是否有任何錯(cuò)誤,我們可以使用像if len(errs) != 0.
package main
import (
"fmt"
)
func processBatch(num int, errChan chan<- error, resultChan chan<- int) {
if num == 3 {
// no need to send result when it is meanenless
// resultChan <- 0
errChan <- fmt.Errorf("goroutine %d's error returned", num)
} else {
square := num * num
resultChan <- square
// no need to send errror when it is nil
// errChan <- nil
}
}
func main() {
batches := [5]int{1, 2, 3, 4, 5}
resultChan := make(chan int)
errChan := make(chan error)
for i := range batches {
go processBatch(batches[i], errChan, resultChan)
}
// use slices instead of arrays because legth varry now
var results []int
var errs []error
// every time function executes it sends singe piece of data to one of two channels
for range batches {
select {
case res := <-resultChan:
results = append(results, res)
case err := <-errChan:
errs = append(errs, err)
}
}
close(resultChan)
close(errChan)
fmt.Println(results)
fmt.Println(errs)
}
https://go.dev/play/p/SYmfl8iGxgD
[25 1 16 4]
[goroutine 3's error returned]
如果你可以使用外部包,我們可以從一些multierr包中獲益。例如,github.com/hashicorp/go-multierror。
- 1 回答
- 0 關(guān)注
- 122 瀏覽
添加回答
舉報(bào)