函数返回后不改变指针

标签 function pointers go reference return

语言是“Go”(“Golang”)。

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

为什么会这样?

代码在这里: 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"
}

输出如下:

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

谢谢!

最佳答案

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

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

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

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

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

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

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

func main() {
    var obj = initApp()
    fmt.Println(obj)
}

关于函数返回后不改变指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52969722/

相关文章:

C - 打印未定义的数组元素不会给我垃圾

c 指向字符串数组的指针数组

go - 我可以在使用预停止 Hook 进行硬驱逐之前优雅地终止进程吗?

json - 是否可以绑定(bind)到自定义结构类型的 map 对象?

JavaScript 指针函数

从 C 函数调用/执行 node.js 脚本

swift - 如何检查 swift 中的嵌入式函数定义?

python - 类型错误 : unorderable types: float() < function()

c++ - 为什么变量指针包含相同数据类型的地址?

debugging - GoGland 中的调试器配置