通过函数将指针设置为nil

3

有一个函数可以将指针设置为nil值:

func nilSetter(x *int) {
    x = nil
}

我有这样的代码片段:

i := 42
fmt.Println(&i)
nilSetter(&i)
fmt.Println(&i)

这将输出:

0xc42008a000
0xc42008a000

我期望:

0xc42008a000
nil

我知道这是因为函数nilSetter只是复制地址并将该副本设置为nil。

但是我应该如何正确地做呢?

3个回答

3
这种行为的原因是因为Go语言中没有按引用传递的方式。 两个变量可以具有指向同一存储位置的内容,但无法共享同一存储位置。 例如:
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-no-pass-by-reference-in-go


2
唯一实现这个的方法是使用指向指针的指针。而且这种方式相当笨重,可能不是你想要的:
func nilSetter(x **int) {
    *x = nil
}

func main() {
    x := 2
    xp := &x

    fmt.Println(xp)
    nilSetter(&xp)
    fmt.Println(xp)

}

// Output:
// 0x10414020
// <nil>

你应该使用fmt.Println(&x)而不是fmt.Println(&xp) - Kenenbek Arzymatov
@KenenbekArzymatov 参考 @maksadbek 的答案。在 Go 中无法更改 &x 的值。 - Chris Redford

0

只需使用返回值并进行赋值。

func nilSetter(x *int) *int {
    x = nil
    return x
}

x = nilSetter(x)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接