這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
軟硬體環境
什麼是介面?
介面定義了一組方法,但是這些方法不包含實現的代碼,另外介面裡也不能包含變數。如下定義了一個介面
type intfNamer interface { Method1(param_list) return_type Method2(param_list) return_type ...}
為什麼要設計介面?
Go不是傳統意義上的物件導向程式設計語言,它沒有類及其繼承的概念。介面是一種契約,實作類別型必須滿足它,它描述了類型的行為,規定類型可以做什麼。介面徹底將類型能做什麼,以及如何做分離開來,使得相同介面的變數在不同的時刻表現出不同的行為,這就是多態的本質。
簡單介面樣本
package mainimport ( "fmt")type namer interface { area() int}type rect struct { width,height int}type square struct { side int}func (r rect) area() int { return r.height * r.width}func (s square) area() int { return s.side * s.side}func main() { var a = rect{4,3} var b = square{6} fmt.Println(a.area()) fmt.Println(b.area())}
程式執行結果為
mtqq_mosquitto
測試某個值是否實現了某個介面?
type Stringer interface { String() string}if sv, ok := v.(Stringer); ok { fmt.Printf("v implements String(): %s\n", sv.String()) // note: sv, not v}
介面嵌套
一個介面可以包含一個或者多個其它的介面,如下
type ReadWrite interface { Read(b Buffer) bool Write(b Buffer) bool}type Lock interface { Lock() Unlock()}type File interface { ReadWrite Lock Close()}
File介面包含了ReadWrite介面、Lock介面和方法Close,任何實現了File介面的類型同時也實現了介面ReadWrite和Lock
需要注意的點
- 類型不需要顯式地聲明它實現了某個介面,介面被隱式地實現,多個類型可以實現同一個介面
- 一個類型可以實現多個介面
- 實現了某個介面的類型,可以有其它的方法
介面方法中類型T和T*的區別
type typeA struct {}type intfA interface { func1()}func (a *typeA) func1() {}func func2(i intfA) { i.func1()}var a typeA
上面的例子中,在a上調用func2時,會導致一個編譯器錯誤,因為func2需要一個intfA,而它的方法func1之定義在指標上。
Go 語言規範定義了介面方法集的調用規則:
- 類型 T 的可調用方法集包含接受者為 T 或 T 的所有方法集
- 類型 T 的可調用方法集包含接受者為 T 的所有方法
- 類型 T 的可調用方法集不包含接受者為 *T 的方法
小結
綜上所述,介面就是一組方法的集合。 只要一個類型實現了某個介面中的方法,那麼,這個介面類型的變數就可以接受這個類型的變數,而且同一個介面,可以接收不同類型的變數。