深入了解Golang?interface{}的底層原理實(shí)現(xiàn)
前言
在 Go
語言沒有泛型之前,接口可以作為一種替代實(shí)現(xiàn),也就是萬物皆為的 interface
。那到底 interface
是怎么設(shè)計(jì)的底層結(jié)構(gòu)呢?下面咱們透過底層分別看一下這兩種類型的接口原理。感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
interface數(shù)據(jù)結(jié)構(gòu)
golang
中的接口分為帶方法的接口和空接口。 帶方法的接口在底層用iface
表示,空接口的底層則是eface
表示。下面咱們透過底層分別看一下這兩種數(shù)據(jù)結(jié)構(gòu)。
iface
iface表示的是包含方法的interface;例如:
type Test interface{ test() }
底層源代碼是:
//runtime/runtime2.go //非空接口 type iface struct { tab *itab data unsafe.Pointer //data是指向真實(shí)數(shù)據(jù)的指針 } type itab struct { inter *interfacetype //描述接口自己的類型 _type *_type //接口內(nèi)部存儲(chǔ)的具體數(shù)據(jù)的真實(shí)類型 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是指向方法集的指針。它用于動(dòng)態(tài)調(diào)度。 } //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相同的是都有指向具體數(shù)據(jù)的指針data字段。 不同的是_type變成了tab。
- hash 是對(duì) _type.hash 的拷貝,當(dāng)我們想將 interface 類型轉(zhuǎn)換成具體類型時(shí),可以使用該字段快速判斷目標(biāo)類型和具體類型 runtime._type 是否一致;
- fun 是一個(gè)動(dòng)態(tài)大小的數(shù)組,它是一個(gè)用于動(dòng)態(tài)派發(fā)的虛函數(shù)表,存儲(chǔ)了一組函數(shù)指針。雖然該變量被聲明成大小固定的數(shù)組,但是在使用時(shí)會(huì)通過原始指針獲取其中的數(shù)據(jù);
eface
eface顧名思義 empty interface,代表的是不包含方法的interface,例如:
type Test interface {}
因?yàn)榭战涌诓话魏畏椒?,所以它的結(jié)構(gòu)也很簡單,底層源代碼是:
//空接口 type eface struct { _type *_type //接口內(nèi)部存儲(chǔ)的具體數(shù)據(jù)的真實(shí)類型 data unsafe.Pointer //data是指向真實(shí)數(shù)據(jù)的指針 } //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 結(jié)構(gòu)體主要包含兩個(gè)字段,共16字節(jié)。
- _type:這個(gè)是運(yùn)行時(shí) runtime._type 指針類型,表示數(shù)據(jù)類型
- data: 表示的數(shù)據(jù)指針
總結(jié)
Go語言底層對(duì)非空interface
和空interface
實(shí)現(xiàn)上做了區(qū)分???code>interface的底層結(jié)構(gòu)是eface
結(jié)構(gòu)。它與iface
的區(qū)別在于,它擁有的不再是 *itab
類型數(shù)據(jù),而是 _type
類型的數(shù)據(jù)。是因?yàn)椋?code>eface面向的是空的interface
數(shù)據(jù),既然是空的interface
,那么只需要用 *_type
代表類型,data
字段指向具體數(shù)據(jù)即可。這里的 *_type
是此interface
代表的數(shù)據(jù)的類型。
到此這篇關(guān)于深入了解Golang interface{}的底層原理實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Golang interface{}內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一站式解決方案:在Windows和Linux上快速搭建Go語言開發(fā)環(huán)境
本文將介紹如何在Windows和Linux操作系統(tǒng)下搭建Go語言開發(fā)環(huán)境,以幫助您更高效地進(jìn)行Go語言開發(fā),需要的朋友可以參考下2023-10-10探究gRPC?客戶端調(diào)用服務(wù)端需要連接池嗎?
這篇文章主要為大家介紹了gRPC?客戶端調(diào)用服務(wù)端需要連接池嗎的問題探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Goland 的安裝及激活教程(window、linux下安裝)
這篇文章主要介紹了Golang Goland 的安裝及激活詳細(xì)教程,包括window下安裝goland和linux下安裝goland,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10