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 關注
- 155 瀏覽
添加回答
舉報
0/150
提交
取消