在“掌握并行中的并发”一书中有一段话让我觉得我可能会遗漏一些关于“延迟”功能的东西。
您还应注意,通过引用传递的任何数据可能处于意外状态。
func main() {
aValue := new(int)
defer fmt.Println(*aValue)
for i := 0; i < 100; i++ {
*aValue++
}
}
这打印0,我想,因为根据规范:
每次执行“延迟”语句时,调用的函数值和参数将照常评估并重新保存
也就是说,当调用defer时,* aValue为0,这就是为什么在结束时它打印0.在这种情况下指针是否被传递给distinct函数是无关紧要的。
我的理解是正确还是我错过了什么?
答案 0 :(得分:2)
考虑使用结构的情况。
type User struct {
Name string
}
func main() {
user := User{}
defer fmt.Printf("%#v\n", user)
user.Name = "AJ"
}
您知道defer
应该在最后运行,因此您可能希望看到User{Name: "AJ"}
,而是获得User{Name: ""}
,因为defer
会绑定参数。
如果你使用指针就可以了。
user := &User{}
如果使用闭包,它可以工作。
defer func() {
fmt.Printf("%#v\n", user)
}()
答案 1 :(得分:1)
延迟声明是&#34;评估&#34;参数和保存结果,并且在延迟呼叫时评估*aValue
的结果为0。这样的事情可能是你正在寻找的东西:
func main() {
aValue := new(int)
defer func() { fmt.Println(*aValue) }()
for i := 0; i < 100; i++ {
*aValue++
}
}