golang 數組的一些自問自答
所有程式碼基於Go-1.17。一些研究Go數組的自問自答,可以考慮作為面試題。
問題:靜態存儲區是什麼?和堆/棧有什麼區別?
回答:
可以參考下列圖
堆上存放new產生的大塊記憶體
棧上存放的是程式運行的時候使用的局部變數記憶體
程式碼段和數據段可以統一稱為靜態存儲區
程式碼段存放的就是程式的二進位文件
數據段存放的包含三個部分:
- 只讀數據段
- 一般是const修飾的變數,不需要修改的
- 已初始化的讀寫數據段
- 已初始化的全局變數
- 已經初始化的靜態局部變數
- 未初始化段
- 未初始化的全局變數
- 未初始化的靜態變數
問題:數組的初始化是在棧上,還是在數據段上的?
回答:
如果是非字面量數組類型,會在棧上初始化
如果是字面量類型:
當元素少於或者等於4個的時候,會直接將數組元素在棧上初始化
當元素大於4個的時候,會在數據段初始化,在使用的時候,複製到棧上
具體可以參考
cmd/compile/internal/walk/complit.go的 anylit
問題: 數組的結構是什麼樣子的?
數組在記憶體中是一段連續的記憶體。
它的類型為:
裡面存放了Bound,元素個數,和Elem 單個元素的類型。
問題:go訪問數組的下標越界是運行時候發現的還是編譯期發現的?
回答:
兩個階段都有可能,對於可以靜態檢測出來的,在編譯器就會報錯。
比如程式碼:
具體使用的是 cmd/compile/internal/typecheck/expr.go 的 tcIndex 方法
但是如果是使用變數下標來訪問,就只能在運行期間來判斷是否越界。通過彙編碼大致能看到最後調用panicIndex
參考
//blog.csdn.net/chen1083376511/article/details/54930191