我正在学习围棋,有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
...
这可能会有所帮助:分配效率。
此外,看到指向切片的指针不太常见,因为切片很小:指针、长度和容量。请参阅切片内部。