函数返回后不改变指针

Che*_*vek 0 pointers return reference function go

语言是'Go'('Golang')。

该函数initApp正在接收一个指向对象的指针(Go 中的“结构”)。在函数内部,我创建了一个新的对象指针并初始化了对象的值。打印和调试器都表明在函数返回之前一切都很好。但是在返回之后,作为函数参数的指针具有与函数调用之前相同的空值。

为什么呢?

代码在这里:https : //pastebin.com/0Gww2CQC

// ptr.go.

package main

import "fmt"

type ClassX struct {
    Name string
    Age  int
}

func main() {
    var obj *ClassX
    initApp(obj)
    fmt.Println(obj)
    return
}

func initApp(x *ClassX) {
    tmp := NewClassXObject()
    x = tmp
    fmt.Println("tmp:", tmp)
    fmt.Println("x:", x)
}

func NewClassXObject() *ClassX {
    x := new(ClassX)
    x.init()
    return x
}

func (o *ClassX) init() {
    o.Age = 123
    o.Name = "John"
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

tmp: &{John 123} x: &{John 123} <nil>

谢谢你!

Adr*_*ian 6

请记住,Go 中的所有内容都是按值传递的。当您传递指针时,您是按值传递指针。您的函数参数是一个新的局部变量,其值与调用者传递给它的值相同;即指向相同内存位置的新指针。所以你的代码:

func initApp(x *ClassX) {
    tmp := NewClassXObject()
    x = tmp
    fmt.Println("tmp:", tmp)
    fmt.Println("x:", x)
}
Run Code Online (Sandbox Code Playgroud)

创建一个新的*ClassXin tmp,然后x用指向新内存位置的新指针覆盖,然后返回。这些都不会对调用者的范围产生任何影响;调用者传递的指针仍然指向它之前所做的相同内存地址。您可以更改x指向的值:

func initApp(x *ClassX) {
    tmp := NewClassXObject()
    *x = *tmp
    fmt.Println("tmp:", tmp)
    fmt.Println("x:", x)
}
Run Code Online (Sandbox Code Playgroud)

现在您有两个指向两个单独内存位置的指针,并且您将一个指向的值复制到另一个指向的内存中,以便它们都指向两个单独的内存位置中的两个相同值。如果您想覆盖调用者指向的值,这就是您要做的。

但是,由于这会创建一个新值,因此您想要的似乎不是覆盖调用者的值,而是返回一个新值。在 Go 中,指针作为“输出参数”的使用非常非常有限;因为您可以返回多个值,所以您几乎总是只想返回值而不是更新指针参数:

func initApp() *ClassX {
    return NewClassXObject()
}

func main() {
    var obj = initApp()
    fmt.Println(obj)
}
Run Code Online (Sandbox Code Playgroud)