淺談Go語言中的接口類型
接口(interface)定義了一個對象的行為規(guī)范,只定義規(guī)范不實現(xiàn),由具體的對象來實現(xiàn)規(guī)范的細節(jié)。
1.接口類型
1.1 接口類型的說明
Go語言中 接口(interface) 是一種抽象的類型。
接口(interface) 是一組 方法 的集合,是 duck-type programming(鴨子類型) 的一種體現(xiàn),接口所做的事情就像是定義一個協(xié)議(規(guī)則),只要一臺機器有洗衣和甩干的功能,就稱之為洗衣機,不關心屬性(數(shù)據(jù)),只關心行為(方法)。
1.2 接口類型的定義
Go語言提倡面向接口編程。
接口是一個或多個方法簽名的集合。
任何類型的方法集中只要擁有該接口'對應的全部方法'簽名。
就表示它 "實現(xiàn)" 了該接口,無須在該類型上顯式聲明實現(xiàn)了哪個接口。
這稱為Structural Typing。
所謂對應方法,是指有相同名稱、參數(shù)列表 (不包括參數(shù)名) 以及返回值。
當然,該類型還可以有其他方法。接口只有方法聲明,沒有實現(xiàn),沒有數(shù)據(jù)字段。
接口可以匿名嵌入其他接口,或嵌入到結(jié)構(gòu)中。
對象賦值給接口時,會發(fā)生拷貝,而接口內(nèi)部存儲的是指向這個復制品的指針,既無法修改復制品的狀態(tài),也無法獲取指針。
只有當接口存儲的類型和對象都為nil時,接口才等于nil。
接口調(diào)用不會做receiver的自動轉(zhuǎn)換。
接口同樣支持匿名字段方法。
接口也可實現(xiàn)類似OOP中的多態(tài)。
空接口可以作為任何類型數(shù)據(jù)的容器。
一個類型可實現(xiàn)多個接口。
接口命名習慣以 er 結(jié)尾。
每個接口由數(shù)個方法組成,接口的定義格式如下:
type 接口類型名 interface{
方法名1( 參數(shù)列表1 ) 返回值列表1
方法名2( 參數(shù)列表2 ) 返回值列表2
…
}
其中:
1.接口名:使用type將接口定義為自定義的類型名。Go語言的接口在命名時,一般會在單詞后面添加er,如有寫操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出該接口的類型含義。
2.方法名:當方法名首字母是大寫且這個接口類型名首字母也是大寫時,這個方法可以被接口所在的包(package)之外的代碼訪問。
3.參數(shù)列表、返回值列表:參數(shù)列表和返回值列表中的參數(shù)變量名可以省略。
舉個例子:
type writer interface{
Write([]byte) error
}
這里定義了一個 writer 的 接口(interface),能夠看到的就只是這個接口定義了一個 Write 方法,具體實現(xiàn)什么功能也不可知。
1.3 實現(xiàn)接口的條件
一個對象只要全部實現(xiàn)了接口中的方法,那么就實現(xiàn)了這個接口。換句話說,接口就是一個需要實現(xiàn)的方法列表。
舉個例子,這里我們定義一個 Phone 對象
type Phone interface {
Call()
SendMessage()
}
定義 OPPO 和 HUAWEI 兩個結(jié)構(gòu)體:
type OPPO struct {
Name string
Price float64
}
type HUAWEI struct {
Name string
Price float64
}
Phone 接口中有兩個方法 Call 和 SendMessage 方法,因此需要給 OPPO 和 HUAWEI 實現(xiàn) Call 和 SendMessage 方法就實現(xiàn)了 Phone 接口。
func (oppo OPPO) Call() {
fmt.Printf("%s 有打電話的功能 \n", oppo.Name)
}
func (oppo OPPO) SendMessage() {
fmt.Printf("%s 有發(fā)短信的功能 \n", oppo.Name)
}
func (huawei HUAWEI) Call() {
fmt.Printf("%s 有打電話的功能 \n", huawei.Name)
}
func (huawei HUAWEI) SendMessage() {
fmt.Printf("%s 有發(fā)短信的功能 \n", huawei.Name)
}
接口的實現(xiàn)就是這樣,只要實現(xiàn)了接口中的所有方法,就實現(xiàn)了這個接口。
1.4 接口變量類型
接口類型變量能夠存儲所有實現(xiàn)了該接口的實例。如上 1.3 實現(xiàn)接口的條件 舉例所示,Phone 類型的變量能夠存儲 HUAWEI 和 OPPO 類型的變量。
func interfaceVariable() {
// 聲明一個Phone 類型的變量x
var x GoInterface.Phone
// 實例化一個OPPO
findx6 := GoInterface.OPPO{
Name: "Find X6",
Price: 5999,
}
// 實例化一個HUAWEI
p30 := GoInterface.HUAWEI{
Name: "HUAWEI P30",
Price: 3999,
}
// 可以把OPPO實例直接賦值給x
x = findx6
x.Call()
// 可以把HUAWEI實例直接賦值給x
x = p30
x.Call()
}
2. 類型與接口之間的關系
2.1 一個類型實現(xiàn)多個接口
一個類型可以同時實現(xiàn)多個接口,而接口間彼此獨立,不知道對方的實現(xiàn)。 例如,OPPO 手機可以打電話,也可以發(fā)短信。我們就分別定義 Caller 接口和 Message 接口,如下:
type Caller interface {
Call()
}
type Message interface {
SendMessage()
}
OPPO 既可以實現(xiàn) Caller 接口,也可以實現(xiàn) Message 接口。
type OPPO struct {
Name string
Price float64
}
// 實現(xiàn)Caller接口
func (oppo OPPO) Call() {
fmt.Printf("%s支持打電話功能\n", oppo.name)
}
// 實現(xiàn)Message接口
func (oppo OPPO) SendMessage() {
fmt.Printf("%s支持發(fā)短信功能\n", oppo.name)
}
func main() {
var x Caller
var y Message
var a = OPPO{Name: "Find X6", Price:5999,}
x = a
y = a
x.Call()
y.SendMessage()
}
2.2 多個類型實現(xiàn)同一接口
Go語言中不同的類型還可以實現(xiàn)同一接口,首先我們定義一個 Caller 接口,它要求必須由一個 Call 方法。
type Caller interface {
Call()
}
例如,HUAWEI 手機可以打電話,OPPO 也可以打電話。
type OPPO struct {
Name string
Price float64
}
type HUAWEI struct {
Name string
Price float64
}
// OPPO 類型實現(xiàn)Caller接口
func (oppo OPPO) Call() {
fmt.Printf("%s 有打電話的功能 \n", oppo.Name)
}
// HUAWEI 類型實現(xiàn)Caller接口
func (huawei HUAWEI) Call() {
fmt.Printf("%s 有打電話的功能 \n", huawei.Name)
}
并且一個接口的方法,不一定需要由一個類型完全實現(xiàn),接口的方法可以通過在類型中嵌入其他類型或者結(jié)構(gòu)體來實現(xiàn)。
// Phone
type Phone interface {
NFC()
Call()
}
// NFC模塊
type NFCER struct{}
// 實現(xiàn)Phone接口的NFC()方法
func (nfc NFC) NFC() {
fmt.Println("NFC刷卡")
}
// OPPO手機
type OPPO struct {
NFCER //嵌入NFC模塊
}
// 實現(xiàn)Phone接口的Call()方法
func (oppo OPPO) Call() {
fmt.Println("OPPO手機支持打電話功能")
}
3.空接口
3.1 空接口的定義
空接口是指沒有定義任何方法的接口。因此任何類型都實現(xiàn)了空接口。
空接口類型的變量可以存儲任意類型的變量。
func emptyInterface() {
// 定義一個空接口x
var x interface{}
s := "euansu.cn"
x = s
fmt.Printf("type:%T value:%v\n", x, x)
i := 100
x = i
fmt.Printf("type:%T value:%v\n", x, x)
b := true
x = b
fmt.Printf("type:%T value:%v\n", x, x)
}
3.2 空接口的應用
空接口可以實現(xiàn)接口任意類型的函數(shù)參數(shù)。
// 空接口作為函數(shù)參數(shù)
func funcMethod(a interface{}) {
fmt.Printf("type:%T value:%v\n", a, a)
}
空接口可以作為 map 的值。
// 空接口作為map值
var studentInfo = make(map[string]interface{})
studentInfo["name"] = "李白"
studentInfo["age"] = 18
studentInfo["married"] = false
fmt.Println(studentInfo)
參考鏈接
[1] 接口
到此這篇關于淺談Go語言中的接口類型的文章就介紹到這了,更多相關Go語言接口類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解Golang中string的實現(xiàn)原理與高效使用
在Go語言中,無論是字符串常量、字符串變量還是代碼中出現(xiàn)的字符串字面量,它們的類型都被統(tǒng)一設置為string,下面就跟隨小編一起來了解一下Golang中string的實現(xiàn)原理與高效使用吧2024-01-01
Go?Gin框架優(yōu)雅重啟和停止實現(xiàn)方法示例
Web應用程序中,有時需要重啟或停止服務器,無論是因為更新代碼還是進行例行維護,這時需要保證應用程序的可用性和數(shù)據(jù)的一致性,就需要優(yōu)雅地關閉和重啟應用程序,即不丟失正在處理的請求和不拒絕新的請求,本文將詳解如何在Go語言中使用Gin這個框架實現(xiàn)優(yōu)雅的重啟停止2024-01-01
Golang實現(xiàn)的聊天程序服務端和客戶端代碼分享
這篇文章主要介紹了Golang實現(xiàn)的聊天程序服務端和客戶端代碼分享,本文先是講解了實現(xiàn)邏輯,然后給出了實現(xiàn)代碼,需要的朋友可以參考下2014-10-10

