通过引用“延迟”传递的数据

时间:2017-01-04 18:53:25

标签: go

在“掌握并行中的并发”一书中有一段话让我觉得我可能会遗漏一些关于“延迟”功能的东西。

您还应注意,通过引用传递的任何数据可能处于意外状态。

func main() {
    aValue := new(int)
    defer fmt.Println(*aValue)

    for i := 0; i < 100; i++ {
         *aValue++
    }
}

这打印0,我想,因为根据规范:

  

每次执行“延迟”语句时,调用的函数值和参数将照常评估并重新保存

也就是说,当调用defer时,* aValue为0,这就是为什么在结束时它打印0.在这种情况下指针是否被传递给distinct函数是无关紧要的。

我的理解是正确还是我错过了什么?

2 个答案:

答案 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++
    }
}
相关问题