Go 转义分析之前的变量生命周期是什么?

Go 转义分析之前的变量生命周期是什么?,go,Go,首先,如果这是一个明显或直截了当的答案,我表示歉意,但我似乎无法理解下面代码的确切过程 package main import ( "fmt" ) func xyz() *int { n := 42 return &n } func main() { num := xyz() fmt.Println("The number is", *num) } 我的问题是,变量n是否在转义分析之前分配给堆栈,一旦超出范围,是否在分配给堆之前进行垃圾收集

首先,如果这是一个明显或直截了当的答案,我表示歉意,但我似乎无法理解下面代码的确切过程

package main

import (
    "fmt"
)

func xyz() *int {
    n := 42
    return &n
}

func main() {
    num := xyz()
    fmt.Println("The number is", *num)
}

我的问题是,变量n是否在转义分析之前分配给堆栈,一旦超出范围,是否在分配给堆之前进行垃圾收集?返回函数xyz时,Golang如何处理指针?我要求一点技术性的一步一步的流程,但也要消除任何知识缺口。

Escape analysis在编译时工作。当编译器意识到变量
n
的地址离开函数时,它编译一个如下所示的函数:

func xyz() *int {
    n:=newInHeap(int)
    *n := 42
    return n
}
这里,
newInHeap
是一个假设函数,它总是在堆中分配变量。如果变量没有退出函数,则常规
new
可以在堆栈上分配变量


返回指针的生存期在运行时由常规GC规则控制。

转义分析在编译时进行;分配是在运行时进行的。哦,哇,是的,这让我明白了。编译器使用new()是有道理的。请注意,这不一定就是它所做的,但效果是一样的。编译器不使用“new”。它创建了同一逻辑概念的类似于中间程序集的表示形式。使用
new
并不意味着堆分配,如果
new(int)没有离开堆栈,您可以很容易地在转义分析中找到它。@JimB,我编辑了答案以反映这一点。