在 goroutine 中将函数作为参数传递

问题描述 投票:0回答:1
import (
    "fmt"
    "time"
)

func WithRecover(r func()) {
    r()
}

func printRewardAmount(rewardAmount int) {
    fmt.Println(rewardAmount)
}

func main() {
    var rewardAmount int
    rewardAmount = 1
    go WithRecover(func() { printRewardAmount(rewardAmount) })
        if true {
        rewardAmount = 2
        }
    time.Sleep(100 * time.Millisecond)
}

当我们将rewardAmount作为值传递时,输出应该是1。但有时我会得到2,有人能解释一下为什么吗?

function go arguments goroutine
1个回答
0
投票

在 Golang 中,当您将变量作为参数传递给 goroutine 时,您将在创建 goroutine 时捕获该变量的值,而不是在执行它时。这意味着 goroutine 捕获

rewardAmount
的当前值,该值可能是 1 或 2,具体取决于 goroutine 执行的时间。

在您的代码中,您有一个运行

WithRecover
的 goroutine,它又调用
printRewardAmount(rewardAmount)
。在创建 Goroutine 之后但在调用
rewardAmount
之前,
main
变量在
time.Sleep
函数中被修改。如果 goroutine 在修改
rewardAmount
之前执行,它将捕获值 1,并且您将看到 1 作为输出。但是,如果
rewardAmount
的修改发生在 goroutine 执行之前,它将捕获值 2,并且您将看到 2 作为输出。

goroutine 的执行顺序无法保证,取决于 Go 调度器。这就是为什么您在不同时间观察到不同输出的原因。如果你想确保 goroutine 将

rewardAmount
的值捕获为 1,你可以将其作为参数传递给 goroutine:

go WithRecover(func(rewardAmount int) { printRewardAmount(rewardAmount) }, rewardAmount)

这样,您可以显式地将

rewardAmount
的当前值作为参数传递给 goroutine,确保它捕获正确的值。

© www.soinside.com 2019 - 2024. All rights reserved.