在 Go 中追加为指针的局部变量的生存期



我正在学习围棋,有C/C++背景。在以下示例中,将a的地址附加到切片中是否安全?当我运行此示例时,打印了正确的值(2(,但希望确定。如果这是错误的,我应该怎么做?

func add(mapping map[string]*[]*int) {
sliceptr := &[]*int{}
mapping["foo"] = sliceptr
ele := mapping["foo"]
a := 2
// won't address of `a` go out of scope?
ele2 := append(*ele, &a)
mapping["foo"] = &ele2
}
func main() {       
mapping := map[string]*[]*int{}    
add(mapping)        
fmt.Println(*(*mapping["foo"])[0])
}

在声明a结束的函数之后引用它是安全的,因为 go 会进行转义分析。如果编译器可以证明它可以安全地访问,它会将其放在堆栈上,如果没有,它会将其分配到堆上。

生成标志可以深入了解转义分析:

go build -gcflags "-m" main.go

...
./main.go:10:2: moved to heap: a
...

这可能会有所帮助:分配效率。

此外,看到指向切片的指针不太常见,因为切片很小:指针、长度和容量。请参阅切片内部。

最新更新