網站首頁 編程語言 正文
前言
在 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
相關推薦
- 2022-11-18 Shell實現批量操作文件的方法詳解_linux shell
- 2022-03-12 使用docker部署grafana+prometheus配置_docker
- 2023-02-18 SQLserver中的any和all運算符的用法_MsSql
- 2022-12-23 swift指針及內存管理內存綁定實例詳解_Swift
- 2022-10-14 SpringCloud組件之Feign遠程調用
- 2022-08-01 基于Python編寫一個二維碼生成器_python
- 2022-04-25 python中關于py文件之間相互import的問題及解決方法_python
- 2023-01-19 python中的字符串切割?maxsplit_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支