21天從Java轉向Go之第八天——水滴石穿(介面)
阿新 • • 發佈:2021-12-01
介面
- 一個介面型別定義了一套方法,如果一個具體型別要實現該介面,那麼必須實現介面型別定義中的所有方法。
介面宣告
- 介面字面量語法
interface {
MethodSignature1
MethodSignature2
}
- 介面命名型別使用Type
type InterfaceName interface{
MethodSignature1
MethodSignature2
}
-
空介面 interface{}
-
介面的命名一般以“er ”結尾
-
介面定義的方法宣告不需要func引導
-
在介面定義中,只有方法宣告沒有方法實現。
介面初始化
-
例項賦值介面,如果具體型別的例項的方法集是某個介面的方法集的超集,則該具體型別實現了介面,可將該型別的具體例項賦值給介面型別的變數。介面被初始化後,呼叫介面的方法就相當於呼叫介面繫結的具體型別的方法。
-
介面變數賦值給介面變數
已經初始化的介面型別變數a 直接賦值給另一種介面變數b ,要求 b方法集是a 的方法
的子集。此時 Go 編譯器會在編譯時進行方法集靜態檢查。這個過程也是介面初始化的
方式,此時介面變數b繫結的具體例項是介面變數a繫結的具體例項的副本。
介面方法呼叫
- 介面方法呼叫和普通的函式呼叫是有區別的。介面方法呼叫的最終地址是在執行期決定的,將具體型別變數賦值給介面後,會使用具體型別的方法指標初始化介面變數,當呼叫介面變數
的方法時,實際上是間接地呼叫例項的方法。介面方法呼叫不是一種直接的呼叫,有一定的運
行時開銷。直接呼叫未初始化的介面變數的方法會產生panic。
介面的動態型別和靜態型別
- 動態型別:介面繫結的具體例項的型別稱為介面的動態型別。介面可以繫結不同型別的例項,
- 靜態型別:介面定義時,其型別已經被確定。這個型別叫做介面的靜態型別。介面的靜態型別在其定義時就被確定,靜態型別的本質特徵就是介面的方法簽名集合。
介面的運算
型別斷言
i.(TypeName)
- i必須是介面變數,如果TypeName是一個具體型別名,則型別斷言用於判斷介面變數i繫結的例項型別是否就是具體型別。如果是介面型別名,則型別斷言用於判斷介面變數i繫結的例項型別是否同時實現了TypeName介面
介面斷言的兩種語法
- 直接賦值模式
o:=i.(TypeName)
- comma,ok表示式
if v,ok := i.(TypeName);ok {
}
型別查詢
switch type := i.(TypeName)
case type`:
xxx
case type2:
xxx
default:
xxx