研究 go 中的介面值——我發現了 Russ Cox 的一篇很棒的(可能已經過時的)文章。據它說:
itable 以有關所涉及型別的一些元資料開始,然后成為函式指標串列。
這個 itable 的實作應該來自 src/runtime/runtime2.go:
type itab struct {
inter *interfacetype
_type *_type
hash uint32 // copy of _type.hash. Used for type switches.
_ [4]byte
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}
第一個令人困惑的事情是 - 陣列如何 - 可變大小?其次,假設我們在索引 0 處有一個滿足介面的方法的函式指標,我們可以在哪里存盤第二個/第三個/...函式指標?
uj5u.com熱心網友回復:
編譯后的代碼和運行時訪問fun就像宣告了欄位一樣,fun [n]uintpr其中n介面中的方法數。第二種方法存盤在fun[1],第三種方法存盤在 ,fun[2]依此類推。Go 語言沒有像這樣的可變大小陣列功能,但是可以使用不安全的惡作劇來模擬該功能。
以下是itab 的分配方式:
m = (*itab)(persistentalloc(unsafe.Sizeof(itab{}) uintptr(len(inter.mhdr)-1)*goarch.PtrSize, 0, &memstats.other_sys))
該函式persistentalloc分配記憶體。該函式的第一個引數是要分配的大小。運算式inter.mhdr是介面中方法的數量。
這是在可變大小陣列上創建切片的代碼:
methods := (*[1 << 16]unsafe.Pointer)(unsafe.Pointer(&m.fun[0]))[:ni:ni]
該運算式參考的元素與假設世界中methods[i]的元素相同,其中是長度 > 的可變大小陣列。后面的代碼使用正常的切片語法 with來訪問可變大小的陣列。m.fun[i]m.funimethodsm.fun
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/424140.html
上一篇:Golang切片追加例外
