提示:由于水平有限,如发现有疑问或错误的地方请毫不客气的提出、讨论,我会在第一时间回复,感谢在先
//测试变量逃逸
// go run -gcflags "-m -l" ch6_1.1.go
import (
"fmt"
)
func dummy(b int) int {
var c int
c = b
return c
}
func void() {
}
func main() {
var a int
void()
//a escape 因为在要传入Println来打印
//c escape 因为要在Println打印
fmt.Println(a,dummy(0))
}
func f() {
var x int
x = 1
global = &x
}
func g() {
y := new(int)
*y = 1
}
/
编译器选择在栈上还是在堆上分配局部变量的存储空间,并不是由用var还是new声明变量的方式决定的。f函数里的x变量虽然在函数内部声明但必须在堆上分配,因为它在函数退出后依然可以通过包一级的global变量找到; 用Go语言的术语说,这个x局部变量从函数f中逃逸了。相反,当g函数返回时,变量y将是不可达的,也就是说可以马上被回收的。因此,*y并没有从函数g中逃逸,编译器可以选择在栈上分配y的存储空间(当然也可在堆上分配,然后由Go语言的GC回收这个变量的内存空间),虽然这里用的是new方式。其实在任何时候,你并不需为了编写正确的代码而要考虑变量的逃逸行为,要记住的是,逃逸的变量需要额外分配内存,同时对性能的优化可能会产生细微的影响。/