Go 中燒腦的接口及空接口
基本定義
Go 官方對(duì)于接口的定義是一句話:An interface type is defined as a set of method signatures. 翻譯過(guò)來(lái)就是,一個(gè)接口定義了一組方法的集合。這和 Java 和 PHP 的接口類(lèi)似,定義一組方法而不定義方法的具體實(shí)現(xiàn)。但是與 Java 和 PHP 迥然不同的地方在于 Go 不需要顯式的聲明 implements
關(guān)鍵詞來(lái)繼承接口,一個(gè)類(lèi)型只要實(shí)現(xiàn)了接口中的所有方法,就視作繼承了該接口,是隱式實(shí)現(xiàn)的。來(lái)看一個(gè)基本的使用示例:
// 定義一個(gè)平臺(tái)接口,包含一個(gè)支付方法 type Platform interface { Pay(amount int) error } // 微信平臺(tái) type Wechat struct{} func (w *Wechat) Pay(amount int) error { fmt.Printf("wechat amount: %d\n", amount) return nil } // 支付寶平臺(tái) // 任意值都可以實(shí)現(xiàn)接口,并非一定需要struct type Alipay int func (a Alipay) Pay(amount int) error { fmt.Printf("alipay amount: %d, a: %d\n", amount, a) return nil } func ExamplePlatform() { var ( p Platform w = Wechat{} a Alipay = 1 ) p = &w p.Pay(2) p = &a p.Pay(3) // 這種寫(xiě)法會(huì)報(bào)錯(cuò) // p = w p = a p.Pay(4) // Output: // wechat amount: 2 // alipay amount: 3, a: 1 // alipay amount: 4, a: 1 }
在這個(gè)示例中,我們定義了一個(gè) Platform
接口和兩個(gè)結(jié)構(gòu)體,分別使用了值接收器和指針接收器來(lái)實(shí)現(xiàn)了 Platform
接口。p = w
這行代碼會(huì)報(bào)錯(cuò),究其原因是,對(duì)于使用指針接收器實(shí)現(xiàn)的接口的 Wechat
,只有它的指針會(huì)實(shí)現(xiàn)接口,值不會(huì)實(shí)現(xiàn);而對(duì)于值實(shí)現(xiàn)接口的 Alipay
,指針和值都會(huì)實(shí)現(xiàn)接口。所以 p = a
可以正常運(yùn)行。
接口嵌套
接口可以嵌套另一個(gè)接口:
// 定義一個(gè)平臺(tái)接口,包含一個(gè)支付方法 type Platform interface { Pay(amount int) error User } type User interface { Login() Logout() } // 微信平臺(tái) type Wechat struct{} func (w *Wechat) Pay(amount int) error { fmt.Printf("wechat amount: %d\n", amount) return nil } func (w *Wechat) Login() {} func (w *Wechat) Logout() {}
此時(shí),Wechat
即實(shí)現(xiàn)了 Platform
接口,也實(shí)現(xiàn)了 User
接口。
接口類(lèi)型斷言
再來(lái)看一個(gè)很復(fù)雜的例子,我們將上面的代碼稍作修改,將 Wechat
的 Login
和Logout
提到另一個(gè)結(jié)構(gòu)中,然后使用類(lèi)型斷言判斷 Wechat
是否實(shí)現(xiàn)了 User
接口:
// 定義一個(gè)平臺(tái)接口,包含一個(gè)支付方法 type Platform interface { Pay(amount int) error User } type User interface { Login() Logout() } type UserS struct { } func (u *UserS) Login() {} func (u *UserS) Logout() {} // 微信平臺(tái) type Wechat struct { UserS } func (w *Wechat) Pay(amount int) error { fmt.Printf("wechat amount: %d\n", amount) return nil } func ExamplePlatform() { var ( p Platform w = Wechat{} ) p = &w p.Pay(2) // 類(lèi)型斷言 _, ok := p.(User) fmt.Println(ok) // Output: // wechat amount: 2 // true }
空接口
Go 1.18 新增了一個(gè)新的變量類(lèi)型:any
,其定義如下:
type any = interface{}
其實(shí) any 就是一個(gè)空接口,對(duì)于空接口而言,它沒(méi)有任何方法,所以對(duì)于任意類(lèi)型的值都相當(dāng)于實(shí)現(xiàn)了空接口,這個(gè)概念和另一個(gè)編程概念十分相似,它就是大名鼎鼎的泛型。在 Go 語(yǔ)言中,fmt.Println
函數(shù)的接收值正是一個(gè) any
:
func Println(a ...any) (n int, err error) { return Fprintln(os.Stdout, a...) }
使用空接口搭配類(lèi)型斷言,我們可以設(shè)計(jì)出一個(gè)簡(jiǎn)單的類(lèi)型轉(zhuǎn)換函數(shù),它將任意類(lèi)型的值轉(zhuǎn)為 int:
func ToInt(i any) int { switch v := i.(type) { case int: return v case float64: return int(v) case bool: if v { return 1 } return 0 case string: vint, _ := strconv.Atoi(v) return vint } return 0 }
到此這篇關(guān)于Go 中燒腦的接口的文章就介紹到這了,更多相關(guān)Go 接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Golang創(chuàng)建單獨(dú)的WebSocket會(huì)話
WebSocket是一種在Web開(kāi)發(fā)中非常常見(jiàn)的通信協(xié)議,它提供了雙向、持久的連接,適用于實(shí)時(shí)數(shù)據(jù)傳輸和實(shí)時(shí)通信場(chǎng)景,本文將介紹如何使用 Golang 創(chuàng)建單獨(dú)的 WebSocket 會(huì)話,包括建立連接、消息傳遞和關(guān)閉連接等操作,需要的朋友可以參考下2023-12-12Go?WEB框架使用攔截器驗(yàn)證用戶(hù)登錄狀態(tài)實(shí)現(xiàn)
這篇文章主要為大家介紹了Go?WEB框架使用攔截器驗(yàn)證用戶(hù)登錄狀態(tài)實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Go http client 連接池不復(fù)用的問(wèn)題
這篇文章主要介紹了Go http client 連接池不復(fù)用的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Golang語(yǔ)言如何讀取http.Request中body的內(nèi)容
這篇文章主要介紹了Golang語(yǔ)言如何讀取http.Request中body的內(nèi)容問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03關(guān)于golang中map使用的幾點(diǎn)注意事項(xiàng)總結(jié)(強(qiáng)烈推薦!)
map是一種無(wú)序的基于key-value的數(shù)據(jù)結(jié)構(gòu),Go語(yǔ)言中的map是引用類(lèi)型,必須初始化才能使用,下面這篇文章主要給大家介紹了關(guān)于golang中map使用的幾點(diǎn)注意事項(xiàng),需要的朋友可以參考下2023-01-01golang 如何用反射reflect操作結(jié)構(gòu)體
這篇文章主要介紹了golang 用反射reflect操作結(jié)構(gòu)體的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04