语言是“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/