提问人:dev1417 提问时间:9/4/2023 更新时间:9/4/2023 访问量:102
在 goroutine 中将函数作为参数传递
Passing function as an argument in goroutine
问:
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 个,有人可以解释我为什么吗?
答:
2赞
chinmayan
9/4/2023
#1
go WithRecover(func() { printRewardAmount(rewardAmount) })
在上面的代码中,您只是将 的值仅传递给函数,而不是传递给 go 例程。因此,范围仍然在 go 例程之外(inside )。因此,根据 go 例程的执行顺序,输出可以是 1 或 2。rewardAmount
printRewardAmount()
rewardAmount
main()
只需通过替换为以下内容来查看地址即可rewardAmount
main()
func main() {
var rewardAmount int
rewardAmount = 1
fmt.Println("address of rewardAmount in main:", &rewardAmount)
go WithRecover(func() {
fmt.Println("address of rewardAmount inside go routine:", &rewardAmount)
printRewardAmount(rewardAmount)
})
if true {
rewardAmount = 2
}
time.Sleep(100 * time.Millisecond)
}
但是,当您执行以下操作时,您实际上是在复制 的值并将其传递给 go 例程。因此,输出将始终为 1。rewardAmount
func main() {
var rewardAmount int
rewardAmount = 1
fmt.Println("address of rewardAmount in main:", &rewardAmount)
go func(rewardAmount int) {
fmt.Println("address of rewardAmount inside go routine:", &rewardAmount)
WithRecover(func() {
printRewardAmount(rewardAmount)
})
}(rewardAmount)
if true {
rewardAmount = 2
}
time.Sleep(100 * time.Millisecond)
}
评论
rewardAmount
rewardAmount
main
go printRewardAmount(rewardAmount)