有一个函数将指针设置为nil
值:
func nilSetter(x *int) {
x = nil
}
我有这样的代码段:
i := 42
fmt.Println(&i)
nilSetter(&i)
fmt.Println(&i)
打印:
0xc42008a000
0xc42008a000
我期望:
0xc42008a000
nil
我知道这是因为功能nilSetter
仅复制地址并将其设置为零复制。
但是我该怎么做正确的?
实现这一目标的唯一方法是用指向指针的指针。而且它很笨拙,所以可能不是您想要的:
func nilSetter(x **int) {
*x = nil
}
func main() {
x := 2
xp := &x
fmt.Println(xp)
nilSetter(&xp)
fmt.Println(xp)
}
// Output:
// 0x10414020
// <nil>
这种行为的原因是因为没有参考。
两个变量可以具有指向同一存储位置的内容。但是,不可能让它们共享相同的存储位置。示例:
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
}
从您的代码中,nilSetter
的参数x
指向某些位置,但它具有自己的地址,当您将nil
设置为其时,您正在更改其地址,而不是指向的地址。
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
}
这就是为什么指针始终具有确切地址的原因,即使其值为nil
引用戴夫·切尼(Dave Cheney(的博客文章:https://dave.cheney.net/2017/04/29/there-is-is-no-pass-pass-by-reference-in-reference-in-go- go
只使用返回值并分配。
func nilSetter(x *int) *int {
x = nil
return x
}
x = nilSetter(x)