如何在 Golang 的并发代码中延迟工作

How working defer in concurrency code in Golang

我有一些代码:

...
func Run(tasks []Task, n, m int) error {
    ...
    for i := 0; i < n; i++ {
        go func() {
            defer wg.Done()
            for t := range taskCh {
                if atomic.LoadInt32(&errCount) >= int32(m) {
                    return
                }

                if err := t(); err != nil {
                    atomic.AddInt32(&errCount, 1)
                }
            }
        }()
    }

    for _, t := range tasks {
        taskCh <- t
    }
    close(taskCh)
    wg.Wait()
    if atomic.LoadInt32(&errCount) >= int32(m) {
        err = ErrErrorsLimitExceeded
    }
    ...
}

它工作正常,但为什么在我编写操作 close() wg.Wait 和 if... 时它不起作用?

    ...
    defer func() {
        close(taskCh)
        wg.Wait()
        if atomic.LoadInt32(&errCount) >= int32(m) {
            err = ErrErrorsLimitExceeded
        }
    }()
    for i := 0; i < n; i++ {
    ...

当变量 errCount = 0

这是 golang 的限制,您不能从延迟函数更改 returned 变量。正确的做法是(注意(err error)命名为return值):

package main

import "fmt"

func someFunction() (err error) {
    defer func() {
        err = fmt.Errorf("Some error")
    }()

    err = fmt.Errorf("Some other error")

    return
}

func main() {
    fmt.Println(someFunction())
}

https://goplay.tools/snippet/9fwcqTIwhow