日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

深入了解Golang?interface{}的底層原理實現_Golang

作者:1個俗人 ? 更新時間: 2022-11-30 編程語言

前言

Go 語言沒有泛型之前,接口可以作為一種替代實現,也就是萬物皆為的 interface。那到底 interface 是怎么設計的底層結構呢?下面咱們透過底層分別看一下這兩種類型的接口原理。感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

interface數據結構

golang中的接口分為帶方法的接口和空接口。 帶方法的接口在底層用iface表示,空接口的底層則是eface表示。下面咱們透過底層分別看一下這兩種數據結構。

iface

iface表示的是包含方法的interface;例如:

type Test interface{
    test()
}

底層源代碼是:

//runtime/runtime2.go

//非空接口
type iface struct {
	tab  *itab
	data unsafe.Pointer //data是指向真實數據的指針
}
type itab struct {
	inter  *interfacetype //描述接口自己的類型
	_type  *_type         //接口內部存儲的具體數據的真實類型
	link   *itab
	hash   uint32 // copy of _type.hash. Used for type switches.
	bad    bool   // type does not implement interface
	inhash bool   // has this itab been added to hash?
	unused [2]byte
	fun    [1]uintptr // fun是指向方法集的指針。它用于動態調度。
}

//runtime/type.go
type _type struct {
	size       uintptr
	ptrdata    uintptr // size of memory prefix holding all pointers
	hash       uint32
	tflag      tflag
	align      uint8
	fieldalign uint8
	kind       uint8
	alg        *typeAlg
	// gcdata stores the GC type data for the garbage collector.
	// If the KindGCProg bit is set in kind, gcdata is a GC program.
	// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
	gcdata    *byte
	str       nameOff
	ptrToThis typeOff
}

和eface相同的是都有指向具體數據的指針data字段。 不同的是_type變成了tab。

  • hash 是對 _type.hash 的拷貝,當我們想將 interface 類型轉換成具體類型時,可以使用該字段快速判斷目標類型和具體類型 runtime._type 是否一致;
  • fun 是一個動態大小的數組,它是一個用于動態派發的虛函數表,存儲了一組函數指針。雖然該變量被聲明成大小固定的數組,但是在使用時會通過原始指針獲取其中的數據;

eface

eface顧名思義 empty interface,代表的是不包含方法的interface,例如:

type Test interface {}

因為空接口不包含任何方法,所以它的結構也很簡單,底層源代碼是:

//空接口
type eface struct {
	_type *_type         //接口內部存儲的具體數據的真實類型
	data  unsafe.Pointer //data是指向真實數據的指針
}

//runtime/type.go
type _type struct {
	size       uintptr
	ptrdata    uintptr // size of memory prefix holding all pointers
	hash       uint32
	tflag      tflag
	align      uint8
	fieldalign uint8
	kind       uint8
	alg        *typeAlg
	// gcdata stores the GC type data for the garbage collector.
	// If the KindGCProg bit is set in kind, gcdata is a GC program.
	// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
	gcdata    *byte
	str       nameOff
	ptrToThis typeOff
}

eface 結構體主要包含兩個字段,共16字節。

  • _type:這個是運行時 runtime._type 指針類型,表示數據類型
  • data: 表示的數據指針

總結

Go語言底層對非空interface和空interface實現上做了區分。空interface的底層結構是eface結構。它與iface的區別在于,它擁有的不再是 *itab類型數據,而是 _type 類型的數據。是因為,eface面向的是空的interface數據,既然是空的interface,那么只需要用 *_type 代表類型,data字段指向具體數據即可。這里的 *_type 是此interface代表的數據的類型。

原文鏈接:https://juejin.cn/post/7157625818456260644

欄目分類
最近更新