1 回答

TA貢獻1796條經驗 獲得超4個贊
Waitgroup 在此代碼中是多余的。執行與等待通道結果的循環完美同步。在所有功能完成工作并從通道讀取發布的結果之前,代碼不會向前移動。僅當您的函數需要在結果發布到通道后執行任何工作時才需要 Waitgroup。
我也更喜歡稍微不同的實現。在發布的實現中,我們不會在每次執行函數時將結果和錯誤都發送到通道中。相反,我們可以只發送成功執行的結果,并在代碼失敗時只發送錯誤。
優點是簡化了結果/錯誤處理。我們在沒有nils.
在這個例子中,函數返回一個數字,我們發送它的默認值0以防出錯。如果零可能是合法的函數執行結果,則從成功中過濾出不成功的執行結果可能會很復雜。
與錯誤相同。要檢查我們是否有任何錯誤,我們可以使用像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 關注
- 110 瀏覽
添加回答
舉報