天天看點

Go語言--接口的内部實作1 接口内部實作

1 接口内部實作

毫無疑問,接口是Go語言類型系統的靈魂,是Go語言實作多态和反射的基礎。前面我們結束了接口的基本概念和用法,定義接口隻需要簡單聲明一個方法集合即可,定義新類型時不需要顯式地聲明要實作的接口,接口的使用也很簡單。但這一切語言特性的背後是語言設計者們的智慧:把複雜留給自己,把簡單留給使用者。

接口的底層是如何實作的?如果實作動态調用?接口的動态調用到底需要多大的額外開銷?這是我們需要弄清楚的問題。

<備注> 基于 go1.15版本。

1.1 資料結構

接口變量必須初始化才有意義,沒有初始化的接口變量的預設值是nil。具體類型執行個體傳遞給接口稱為接口的初始化。接口的初始化過程中,編譯器通過特定的資料結構描述這個過程。非空接口的内部資料結構如下:

// src/runtime/runtime2.go
type iface struct {
    tab  *itab            //itab存放類型及方法指針資訊
    data unsafe.Pointer   //資料資訊
}
           

非空接口的初始化過程就是初始化一個 iface 類型的結構體。

  • itab:是一個結構體,用來存放接口自身類型和并綁定的執行個體類型及執行個體相關的函數指針,具體内容下面會詳細介紹。
  • 資料指針data:指向接口綁定的執行個體的副本,接口的初始化也是一種值拷貝。data指向具體的執行個體資料,如果傳遞給接口的是值類型,則data指向的