Reputation: 2144
There is a passage in the "Mastering Concurrency in Go" book which made me think I might be missing something about "defer" functions.
You should also take note that any data passed by reference may be in an unexpected state.
func main() {
aValue := new(int)
defer fmt.Println(*aValue)
for i := 0; i < 100; i++ {
*aValue++
}
}
This prints 0, I thought, because according to spec:
Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew
That is, *aValue is 0 when defer is called and that's why at the end it prints 0. Whether or not a pointer is passed to the differ function in this case is irrelevant.
Is my understanding correct or am I missing something?
Upvotes: 2
Views: 1555
Reputation: 34236
Consider a situation using structs.
type User struct {
Name string
}
func main() {
user := User{}
defer fmt.Printf("%#v\n", user)
user.Name = "AJ"
}
You know defer
should run at the end, so you might expect to see User{Name: "AJ"}
but instead you get User{Name: ""}
because defer
binds parameters.
If you use a pointer it works.
user := &User{}
If you use a closure, it works.
defer func() {
fmt.Printf("%#v\n", user)
}()
Upvotes: 3
Reputation: 7170
The defer statement is "evaluating" the parameters and saving the result, and the result of evaluating *aValue
is 0 at the time of the defer call. Something like this may be what you're looking for:
func main() {
aValue := new(int)
defer func() { fmt.Println(*aValue) }()
for i := 0; i < 100; i++ {
*aValue++
}
}
Upvotes: 2