Pointers 局部变量的返回地址生成意外值

Pointers 局部变量的返回地址生成意外值,pointers,go,stack,Pointers,Go,Stack,我已经写了下面的代码。我知道返回一个变量的地址 在函数中创建是错误的方法,因为创建的局部变量将在堆栈中,并且 完成函数后,变量将从堆栈中弹出。 我创造了一个叫“拉蒂夫”的人。然后我使用了changeName()函数。它将person结构的name字段更改为“uluman”。它已返回局部变量的地址。完成函数后,应弹出局部变量。然后我调用了sum()函数,以确保堆栈将发生变化(sum函数的参数将被按下。换句话说,内存中的单元格值x点应该发生变化)。所以x指向堆栈中的某个地方 package main

我已经写了下面的代码。我知道返回一个变量的地址 在函数中创建是错误的方法,因为创建的局部变量将在堆栈中,并且 完成函数后,变量将从堆栈中弹出。 我创造了一个叫“拉蒂夫”的人。然后我使用了changeName()函数。它将person结构的name字段更改为“uluman”。它已返回局部变量的地址。完成函数后,应弹出局部变量。然后我调用了sum()函数,以确保堆栈将发生变化(sum函数的参数将被按下。换句话说,内存中的单元格值x点应该发生变化)。所以x指向堆栈中的某个地方

package main
    import "fmt"

    type Person struct{
        name string
        age int

    }
    func sum(a, b int)int{
       return a+b
    }
    func (t Person ) changeName(value string)*Person{
        t.name = value
        return &t  //Delibiratly the address of the local variable is returned
    }
    func main(){
        t := Person{name : "latif" }

        fmt.Println("Before" , t.name)
        x := t.changeName("uluman")
        _= sum(5,10)
        fmt.Println("After" , x.name)



        return
    }
我希望fmt.Println(x.name)应该打印与uluman'不同的内容,因为x点堆栈地址已经更改,但它已经打印了“uluman”。 这里出了什么问题?

它被称为“逃逸分析”

Go编译器试图找出变量的地址是否“转义”了函数,如果转义了,则在堆中而不是堆栈中分配变量。在这种情况下,它发现
t
的地址转义了
changeName
函数,因此它是在堆中分配的,而不是在堆栈中。这就是你的程序工作的原因

例如,这是构造结构的常用方法:

type X struct {
  ...
}

func NewX() *X {
   a:=X{}
   ...
   return &a
}
这里,
a
是在堆中分配的,而不是在堆栈上,因为编译器知道
a
会转义函数

以下内容同样有效:

func f() {
  i:=0
  go func() {
    ...
    i++
    ...
   }()
}

上面,
i
转义
f
,因为
i
的地址位于新创建的goroutine的闭包中。
f
返回后,
i
继续有效。

x不指向堆栈地址。请参阅、、等“在函数中创建的变量的地址是错误的方法,因为创建的局部变量将在堆栈中,并且在完成函数后,变量将从堆栈中弹出”false。任何带有指针的变量都将被分配到堆上并由GC管理。@JimB感谢您的响应。我找不到链接。对于堆分配和堆栈分配之间的区别,没有任何说明。事实上,spec不包含“heap”或“stack”这两个词。这个问题是基于一些其他语言的概念包袱。