掌握 Go 語言 Interface:面試高頻考點詳解
一、interface
1、interface 作用
-
接口是 Go 語言的重要組成部分,它在 Go 語言中通過一組方法指定了一個對象的行爲
-
接口 interface 的引入能夠讓我們在 Go 語言更好地組織並寫出易於測試的代碼
-
golang 中的接口分爲帶方法的接口和空接口
-
iface: 表示帶方法的接口
-
eface:表示空接口
2、eface 空接口
-
空接口 eface 結構比較簡單,由兩個屬性構成
-
一個是類型信息_type, 一個是數據信息
-
其數據結構聲明如下:
type eface struct {
_type *_type
data unsafe.Pointer
}
-
其中_type 是 Go 語言中所有類型的公共描述,Go 語言幾乎所有的數據結構都可以抽象成_type,是所有類型的公共描述
-
type 負責決定 data 應該如何解釋和操作
-
type 的結構代碼如下:
type _type struct {
size uintptr
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32 // 類型哈希
tflag tflag
align uint8 // _type作爲整體變量存放時的對齊字節數
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 // type for pointer to this type, may be zero
}
-
data 表示指向具體的實例數據,由於 Go 的參數傳遞規則爲值傳遞
-
如果希望可以通過 interface 對實例數據修改,則需要傳入指針
-
此時 data 指向的是指針的副本,但指針指向的實例地址不變,仍然可以對實例數據產生修改
3、iface 帶方法的接口
-
iface 表示帶方法的數據結構,非空接口初始化的過程就是初始化一個 iface 類型的結構
-
其中 data 的作用同 eface 的相同。這裏不再多加描述
type iface struct {
tab *itab
data unsafe.Pointer
}
-
iface 結構中最重要的是 itab 結構 (結構如下),每一個 itab 都佔 32 字節的空間
-
itab 可以理解爲 pair<interface type,concrete type>
-
itab 裏面包含了 interface 的一些關鍵信息,比如 method 的具體實現
type itab struct {
inter *interfacetype // 接口自身的元信息
_type *_type // 具體類型的元信息
link *itab
bad int32
hash int32 // _type裏也有一個同樣的hash,此處多放一個是爲了方便運行接口斷言
fun [1]uintptr // 函數指針,指向具體類型所實現的方法
}
// interface type包含了一些關於interface本身的信息,比如package path,包含的method
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
type imethod struct { //這裏的 method 只是一種函數聲明的抽象,比如 func Print() error
name nameOff
ityp typeOff
}
4、interface 設計的優缺點
-
優點,非侵入式設計。寫起來更自由,無需顯示實現,只要實現了與 interface 所包含的所有函數簽名相同的方法即可
-
缺點:duck-typing 風格並不關注接口的規則和含義,也沒法檢查,不確定某個 struct 具體實現了那些 interface
-
只能通過 goru 工具查看
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/7eOhqIJxHtnWbHQEencv4w