淺談Go語(yǔ)言中的接口類型
接口(interface)定義了一個(gè)對(duì)象的行為規(guī)范,只定義規(guī)范不實(shí)現(xiàn),由具體的對(duì)象來(lái)實(shí)現(xiàn)規(guī)范的細(xì)節(jié)。
1.接口類型
1.1 接口類型的說(shuō)明
Go語(yǔ)言中 接口(interface)
是一種抽象的類型。
接口(interface)
是一組 方法
的集合,是 duck-type programming(鴨子類型)
的一種體現(xiàn),接口所做的事情就像是定義一個(gè)協(xié)議(規(guī)則),只要一臺(tái)機(jī)器有洗衣和甩干的功能,就稱之為洗衣機(jī),不關(guān)心屬性(數(shù)據(jù)),只關(guān)心行為(方法)。
1.2 接口類型的定義
Go語(yǔ)言提倡面向接口編程。
接口是一個(gè)或多個(gè)方法簽名的集合。
任何類型的方法集中只要擁有該接口'對(duì)應(yīng)的全部方法'簽名。
就表示它 "實(shí)現(xiàn)" 了該接口,無(wú)須在該類型上顯式聲明實(shí)現(xiàn)了哪個(gè)接口。
這稱為Structural Typing。
所謂對(duì)應(yīng)方法,是指有相同名稱、參數(shù)列表 (不包括參數(shù)名) 以及返回值。
當(dāng)然,該類型還可以有其他方法。接口只有方法聲明,沒(méi)有實(shí)現(xiàn),沒(méi)有數(shù)據(jù)字段。
接口可以匿名嵌入其他接口,或嵌入到結(jié)構(gòu)中。
對(duì)象賦值給接口時(shí),會(huì)發(fā)生拷貝,而接口內(nèi)部存儲(chǔ)的是指向這個(gè)復(fù)制品的指針,既無(wú)法修改復(fù)制品的狀態(tài),也無(wú)法獲取指針。
只有當(dāng)接口存儲(chǔ)的類型和對(duì)象都為nil時(shí),接口才等于nil。
接口調(diào)用不會(huì)做receiver的自動(dòng)轉(zhuǎn)換。
接口同樣支持匿名字段方法。
接口也可實(shí)現(xiàn)類似OOP中的多態(tài)。
空接口可以作為任何類型數(shù)據(jù)的容器。
一個(gè)類型可實(shí)現(xiàn)多個(gè)接口。
接口命名習(xí)慣以 er 結(jié)尾。
每個(gè)接口由數(shù)個(gè)方法組成,接口的定義格式如下:
type 接口類型名 interface{ 方法名1( 參數(shù)列表1 ) 返回值列表1 方法名2( 參數(shù)列表2 ) 返回值列表2 … }
其中:
1.接口名:使用type將接口定義為自定義的類型名。Go語(yǔ)言的接口在命名時(shí),一般會(huì)在單詞后面添加er,如有寫操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出該接口的類型含義。
2.方法名:當(dāng)方法名首字母是大寫且這個(gè)接口類型名首字母也是大寫時(shí),這個(gè)方法可以被接口所在的包(package)之外的代碼訪問(wèn)。
3.參數(shù)列表、返回值列表:參數(shù)列表和返回值列表中的參數(shù)變量名可以省略。
舉個(gè)例子:
type writer interface{ Write([]byte) error }
這里定義了一個(gè) writer
的 接口(interface)
,能夠看到的就只是這個(gè)接口定義了一個(gè) Write
方法,具體實(shí)現(xiàn)什么功能也不可知。
1.3 實(shí)現(xiàn)接口的條件
一個(gè)對(duì)象只要全部實(shí)現(xiàn)了接口中的方法,那么就實(shí)現(xiàn)了這個(gè)接口。換句話說(shuō),接口就是一個(gè)需要實(shí)現(xiàn)的方法列表。
舉個(gè)例子,這里我們定義一個(gè) Phone
對(duì)象
type Phone interface { Call() SendMessage() }
定義 OPPO
和 HUAWEI
兩個(gè)結(jié)構(gòu)體:
type OPPO struct { Name string Price float64 } type HUAWEI struct { Name string Price float64 }
Phone
接口中有兩個(gè)方法 Call
和 SendMessage
方法,因此需要給 OPPO
和 HUAWEI
實(shí)現(xiàn) Call
和 SendMessage
方法就實(shí)現(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) }
接口的實(shí)現(xiàn)就是這樣,只要實(shí)現(xiàn)了接口中的所有方法,就實(shí)現(xiàn)了這個(gè)接口。
1.4 接口變量類型
接口類型變量能夠存儲(chǔ)所有實(shí)現(xiàn)了該接口的實(shí)例。如上 1.3 實(shí)現(xiàn)接口的條件
舉例所示,Phone
類型的變量能夠存儲(chǔ) HUAWEI
和 OPPO
類型的變量。
func interfaceVariable() { // 聲明一個(gè)Phone 類型的變量x var x GoInterface.Phone // 實(shí)例化一個(gè)OPPO findx6 := GoInterface.OPPO{ Name: "Find X6", Price: 5999, } // 實(shí)例化一個(gè)HUAWEI p30 := GoInterface.HUAWEI{ Name: "HUAWEI P30", Price: 3999, } // 可以把OPPO實(shí)例直接賦值給x x = findx6 x.Call() // 可以把HUAWEI實(shí)例直接賦值給x x = p30 x.Call() }
2. 類型與接口之間的關(guān)系
2.1 一個(gè)類型實(shí)現(xiàn)多個(gè)接口
一個(gè)類型可以同時(shí)實(shí)現(xiàn)多個(gè)接口,而接口間彼此獨(dú)立,不知道對(duì)方的實(shí)現(xiàn)。 例如,OPPO
手機(jī)可以打電話,也可以發(fā)短信。我們就分別定義 Caller
接口和 Message
接口,如下:
type Caller interface { Call() } type Message interface { SendMessage() }
OPPO
既可以實(shí)現(xiàn) Caller
接口,也可以實(shí)現(xiàn) Message
接口。
type OPPO struct { Name string Price float64 } // 實(shí)現(xiàn)Caller接口 func (oppo OPPO) Call() { fmt.Printf("%s支持打電話功能\n", oppo.name) } // 實(shí)現(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 多個(gè)類型實(shí)現(xiàn)同一接口
Go語(yǔ)言中不同的類型還可以實(shí)現(xiàn)同一接口,首先我們定義一個(gè) Caller
接口,它要求必須由一個(gè) Call
方法。
type Caller interface { Call() }
例如,HUAWEI
手機(jī)可以打電話,OPPO
也可以打電話。
type OPPO struct { Name string Price float64 } type HUAWEI struct { Name string Price float64 } // OPPO 類型實(shí)現(xiàn)Caller接口 func (oppo OPPO) Call() { fmt.Printf("%s 有打電話的功能 \n", oppo.Name) } // HUAWEI 類型實(shí)現(xiàn)Caller接口 func (huawei HUAWEI) Call() { fmt.Printf("%s 有打電話的功能 \n", huawei.Name) }
并且一個(gè)接口的方法,不一定需要由一個(gè)類型完全實(shí)現(xiàn),接口的方法可以通過(guò)在類型中嵌入其他類型或者結(jié)構(gòu)體來(lái)實(shí)現(xiàn)。
// Phone type Phone interface { NFC() Call() } // NFC模塊 type NFCER struct{} // 實(shí)現(xiàn)Phone接口的NFC()方法 func (nfc NFC) NFC() { fmt.Println("NFC刷卡") } // OPPO手機(jī) type OPPO struct { NFCER //嵌入NFC模塊 } // 實(shí)現(xiàn)Phone接口的Call()方法 func (oppo OPPO) Call() { fmt.Println("OPPO手機(jī)支持打電話功能") }
3.空接口
3.1 空接口的定義
空接口是指沒(méi)有定義任何方法的接口。因此任何類型都實(shí)現(xiàn)了空接口。
空接口類型的變量可以存儲(chǔ)任意類型的變量。
func emptyInterface() { // 定義一個(gè)空接口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 空接口的應(yīng)用
空接口可以實(shí)現(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] 接口
到此這篇關(guān)于淺談Go語(yǔ)言中的接口類型的文章就介紹到這了,更多相關(guān)Go語(yǔ)言接口類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang中fsnotify包監(jiān)聽文件變化的原理詳解
Golang提供了一個(gè)強(qiáng)大的fsnotify包,它能夠幫助我們輕松實(shí)現(xiàn)文件系統(tǒng)的監(jiān)控,本文將深入探討fsnotify包的原理,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12golang優(yōu)先級(jí)隊(duì)列的實(shí)現(xiàn)全過(guò)程
優(yōu)先級(jí)隊(duì)列是一種特殊隊(duì)列,下面這篇文章主要給大家介紹了關(guān)于golang優(yōu)先級(jí)隊(duì)列的實(shí)現(xiàn)全過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12golang服務(wù)報(bào)錯(cuò):?write:?broken?pipe的解決方案
在開發(fā)在線客服系統(tǒng)的時(shí)候,看到日志里有一些錯(cuò)誤信息,下面這篇文章主要給大家介紹了關(guān)于golang服務(wù)報(bào)錯(cuò):?write:?broken?pipe的解決方案,需要的朋友可以參考下2022-09-09Golang實(shí)現(xiàn)事務(wù)型內(nèi)存數(shù)據(jù)庫(kù)的方法詳解
內(nèi)存數(shù)據(jù)庫(kù)經(jīng)我們經(jīng)常用到,例如Redis,那么如何從零實(shí)現(xiàn)一個(gè)內(nèi)存數(shù)據(jù)庫(kù)呢,本文旨在介紹如何使用Golang編寫一個(gè)KV內(nèi)存數(shù)據(jù)庫(kù)MossDB2023-03-03Golang 實(shí)現(xiàn)Thrift客戶端連接池方式
這篇文章主要介紹了Golang 實(shí)現(xiàn)Thrift客戶端連接池方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12PHP和GO對(duì)接ChatGPT實(shí)現(xiàn)聊天機(jī)器人效果實(shí)例
這篇文章主要為大家介紹了PHP和GO對(duì)接ChatGPT實(shí)現(xiàn)聊天機(jī)器人效果實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01