先让我们看一段代码 注意 返回值 和 对应的局部变量
func Deserialize(data []byte) *Block {
if len(data) == 0 {
fmt.Println("data is empty!")
os.Exit(1)
}
decoder := gob.NewDecoder(bytes.NewReader(data))
var block Block
err := decoder.Decode(&block)
CheckErr("Deserialize", err)
return &block
}
学过c 或者c++的道友看到这段代码 肯定会说 这段代码是错的 但我们探讨的是go 语言 可以先说一下这段代码在go语言中是对的
关于代码中变量block 在内存的位置 大致的说 是在堆上 而并非栈上
这里要说一下 go预言中变量的生命周期 下面三段 引自 《go语言圣经》
局部变量的声明周期则是动态的:从每次创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。
看到这里 相信 你已经明白了些
关于go语言的垃圾回收器
那么Go语言的自动圾收集器是如何知道一个变量是何时可以被回收的呢?这里我们可以避开完整的技术细节,基本的实现思路是,从每个包级的变量和每个当前运行函数的每一个局部变量开始,通过指针或引用的访问路径遍历,是否可以找到该变量。如果不存在这样的访问路径,那么说明该变量是不可达的,也就是说它是否存在并不会影响程序后续的计算结果。
关于var 和 new 开辟的内存位置
编译器会自动选择在栈上还是在堆上分配局部变量的存储空间,但可能令人惊讶的是,这个选择并不是由用var还是new声明变量的方式决定的。
下面是 引用部分的 的来源 建议大家看一下 打开链接后看最下面的内容就可以了
https://yar999.gitbooks.io/gopl-zh/content/ch2/ch2-03.html