There is a function that sets a pointer to a nil value:
func nilSetter(x *int) {
x = nil
}
I have such snippet of code:
i := 42
fmt.Println(&i)
nilSetter(&i)
fmt.Println(&i)
Which prints:
0xc42008a000
0xc42008a000
While I expect:
0xc42008a000
nil
I know that it happens because function nilSetter just copy address and sets to nil that copy.
But how can I do it correctly?
The reason of such behaviour is because there is no pass by reference in Go.
Two variables can have contents that point to the same storage location. But, it is not possible to have them share the same storage location. Example:
package main
import "fmt"
func main() {
var a int
var b, c = &a, &a
fmt.Println(b, c) // 0x1040a124 0x1040a124
fmt.Println(&b, &c) // 0x1040c108 0x1040c110
}
From your code, the argument x of nilSetter is pointing to some location but it have its own address and when you are setting a nil to it, you are changing its address not the address of what it is pointing to.
package main
import "fmt"
func nilSetter(x *int) {
x = nil
fmt.Println(x, &x) // <nil> 0x1040c140
}
func main() {
i := 42
fmt.Println(&i) // 0x10414020
nilSetter(&i)
fmt.Println(&i) // 0x10414020
}
That is why pointers always have an exact address even its value is nil
Referencing to a blog post by Dave Cheney: https://dave.cheney.net/2017/04/29/there-is-no-pass-by-reference-in-go
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With