Go 使用逃逸分析和垃圾收集来管理堆栈和堆上的内存分配。Go 的常见问题解答还说:我如何知道变量是分配在堆上还是栈上?从正确性的角度来看,您不需要知道。只要有对它的引用,Go 中的每个变量就存在。实现选择的存储位置与语言的语义无关。所以 Go 为变量分配内存,并至少保留它直到需要它。我的问题是:这个(抽象)行为是用Go 编程语言规范编写的吗?我发现分配部分是写的,例如,在分配部分:内置函数new采用 type T,在运行时为该类型的变量分配存储空间,并返回*T指向该类型的值。但是有没有关于预订部分的描述?我们能否确认“Go 中的每个变量只要有引用就存在”这一事实吗?如果没有,有什么原因吗?例如,如果 Go 编译器没有错误,我想确认以下程序不得抛出 SIGSEGV 或类似异常。func foo() *int { x := 42 return &x}func main() { px := foo() fmt.Println(*px)}更准确地说,我希望“Go 在new什么时候分配内存”和“Go 至少在需要时保留分配的内存”这两部分应该写在规范中。我不关心它的实现细节,尽管https://github.com/golang/go使用了逃逸分析和垃圾回收。如果后一部分不存在,那么在极端情况下,根据规范,内存分配后立即取消分配是有效的实现。但这很荒谬,所以我认为规范应该使这一点无效。
3 回答

POPMUISE
TA贡献1765条经验 获得超5个赞
但是有保存部分的说明吗?我们能否确认“Go 中的每个变量只要有引用就存在”这一事实吗?如果没有,有什么原因吗?
不在语言规范中,不;这是运行时的质量,而不是语言。我们可以通过简单地观察 Go 程序实际工作来确认只要有对它的引用就不会收集内存的事实。如果该假设不成立,那么大多数标准库以及几乎所有 Go 开发人员编写的代码都将无效。Go 编译器的逃逸分析和垃圾收集器绝对有效。
您找到的常见问题解答条目是规范的,可以依赖,与规范相同。

LEATH
TA贡献1936条经验 获得超7个赞
您可以想象会导致问题的事情是*px
在 main 函数中。如果指向的东西px
不再存在。但是,根据本节:https ://golang.org/ref/spec#Address_operators
对于指针类型 *T 的操作数 x,指针间接 *x 表示 x 指向的类型 T 的变量。如果 x 为 nil,则尝试评估 *x 将导致运行时恐慌。
这基本上是说 Go 的实现一定会给你指向的值,除非指针nil
在这种情况下会恐慌。规范没有说明实现是如何做到这一点的,但是您可以指望 Go 的任何实现以某种方式做到这一点。
这与您的第一句话所说的相符。
- 3 回答
- 0 关注
- 164 浏览
添加回答
举报
0/150
提交
取消