Go?Interface接口初學(xué)者手冊
Interface接口類型實現(xiàn)
接口是一組方法簽名。如果一個類型在其上定義了給定接口的所有方法,則該類型 "實現(xiàn)" 了該接口。
在以下示例中,“形狀” 必須能夠返回其面積和周長。rect 和 circle 都滿足該接口。
type shape interface { area() float64 perimeter() float64 } type rect struct { width, height float64 } func (r rect) area() float64 { return r.width * r.height } func (r rect) perimeter() float64 { return 2*r.width + 2*r.height } type circle struct { radius float64 } func (c circle) area() float64 { return math.Pi * c.radius * c.radius } func (c circle) perimeter() float64 { return 2 * math.Pi * c.radius }
當(dāng)一個類型實現(xiàn)一個接口時,它可以被用作該接口類型。
接口的實現(xiàn)是隱式的。
類型從不聲明它實現(xiàn)了給定的接口。如果接口存在,并且類型定義了適當(dāng)?shù)姆椒ǎ敲丛擃愋蜁詣訚M足該接口。
Multiple Interfaces
在Go中,一個類型可以實現(xiàn)任意數(shù)量的接口。例如,空接口 interface{}
總是被每種類型實現(xiàn),因為它沒有要求。
Naming interface args
考慮以下接口:
type Copier interface { Copy(string, string) int }
根據(jù)僅有的代碼,你能推斷出應(yīng)該將什么類型的字符串傳遞給 Copy
函數(shù)嗎?
我們知道函數(shù)簽名期望兩個字符串類型,但它們是什么?文件名?URL?原始字符串?dāng)?shù)據(jù)?另外,返回的那個整數(shù)到底是什么?
讓我們添加一些有名的參數(shù)和返回數(shù)據(jù),使其更清晰。
type Copier interface { Copy(sourceFile string, destinationFile string) (bytesCopied int) }
好多了。現(xiàn)在我們可以看到期望是什么了。第一個參數(shù)是 sourceFile
,第二個參數(shù)是 destinationFile
,并返回了一個整數(shù) bytesCopied
。
Type Assertions in Go
在Go中使用接口時,偶爾需要訪問接口值的底層類型。您可以使用類型斷言將接口轉(zhuǎn)換為其底層類型。
type shape interface { area() float64 } type circle struct { radius float64 } // "c" is a new circle cast from "s" // which is an instance of a shape. // "ok" is a bool that is true if s was a circle // or false if s isn't a circle c, ok := s.(circle) if !ok { // s wasn't a circle log.Fatal("s is not a circle") } radius := c.radius
Type Switches in Go
類型開關(guān)使得在一系列中執(zhí)行多個類型斷言變得很容易。
類型開關(guān)類似于常規(guī)的開關(guān)語句,但是情況指定的是類型而不是值。
func printNumericValue(num interface{}) { switch v := num.(type) { case int: fmt.Printf("%T\n", v) case string: fmt.Printf("%T\n", v) default: fmt.Printf("%T\n", v) } } func main() { printNumericValue(1) // prints "int" printNumericValue("1") // prints "string" printNumericValue(struct{}{}) // prints "struct {}" }
fmt.Printf("%T\n", v)
打印變量的類型。
Clean Interfaces
編寫清晰的接口很難。坦率地說,每當(dāng)在代碼中處理抽象概念時,如果不小心,簡單的事情很快就會變得復(fù)雜。讓我們回顧一些保持接口清晰的經(jīng)驗法則。
Keep Interfaces Small
如果你從這篇文章中只記住一點建議,那就是:保持接口的小巧!接口的目的是定義準(zhǔn)確表示一個想法或概念所需的最小行為。
以下是標(biāo)準(zhǔn) HTTP 包中的一個較大接口的示例,它很好地演示了定義最小行為的概念:
type File interface { io.Closer io.Reader io.Seeker Readdir(count int) ([]os.FileInfo, error) Stat() (os.FileInfo, error) }
滿足接口行為的任何類型都可以被 HTTP 包視為 File。這很方便,因為 HTTP 包不需要知道它處理的是磁盤上的文件,網(wǎng)絡(luò)緩沖區(qū)還是簡單的 []byte。
Interfaces Should Have No Knowledge of Satisfying Types
接口應(yīng)該定義其他類型需要滿足的條件以成為該接口的成員。它們在設(shè)計時不應(yīng)該知道任何恰好滿足該接口的類型。
例如,假設(shè)我們正在構(gòu)建一個描述定義汽車所需組件的接口。
type car interface { Color() string Speed() int IsFiretruck() bool }
Color()
和 Speed()
完全有道理,它們是限定在汽車范圍內(nèi)的方法。IsFiretruck()
是一個反模式。我們強制所有汽車聲明它們是否是消防車。為了使這種模式有任何意義,我們需要一個可能的子類型清單。IsPickup()
、IsSedan()
、IsTank()
... 這會無休止地擴展。
相反,開發(fā)人員應(yīng)該依賴于類型斷言的本機功能,在給定汽車接口的實例時推導(dǎo)出底層類型?;蛘?,如果需要子接口,可以這樣定義:
type firetruck interface { car HoseLength() int }
這個接口繼承了 car
所需的方法,并添加了一個額外的必需方法,使車輛成為消防車。
Interfaces Are Not Classes
接口不是類,它們更加輕量。
接口沒有構(gòu)造函數(shù)或析構(gòu)函數(shù),不要求創(chuàng)建或銷毀數(shù)據(jù)。
接口在本質(zhì)上不是層次結(jié)構(gòu),盡管有語法糖可以創(chuàng)建接口,這些接口碰巧是其他接口的超集。
接口定義了函數(shù)簽名,但不定義底層行為。創(chuàng)建接口通常不會在結(jié)構(gòu)方法方,使代碼更加干燥。例如,如果有五種類型滿足 fmt.Stringer
接口,它們都需要有自己版本的 String()
函數(shù)。
以上就是Go Interfaces接口初學(xué)者手冊的詳細內(nèi)容,更多關(guān)于Go Interfaces接口的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go?interface?接口的最佳實踐經(jīng)驗分享
go?的接口在go的編程里面用的十分頻繁,尤其是空接口的使用,因為有了接口,才使得Go語言變得異常的強大,今天給大家介紹下Go?interface?接口的最佳實踐經(jīng)驗分享,感興趣的朋友一起看看吧2022-04-04Go調(diào)度器學(xué)習(xí)之協(xié)作與搶占詳解
如果某個G執(zhí)行時間過長,其他的G如何才能被正常調(diào)度,這就引出了接下來的話題:協(xié)作與搶占。本文將通過一些示例為大家詳細講講調(diào)度器中協(xié)作與搶占的相關(guān)知識,需要的可以參考一下2023-04-04Golang?手寫一個簡單的并發(fā)任務(wù)?manager
這篇文章主要介紹了Golang?手寫一個簡單的并發(fā)任務(wù)?manager,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08Golang Gin框架實現(xiàn)多種數(shù)據(jù)格式返回結(jié)果詳解
這篇文章主要介紹了Golang Gin框架實現(xiàn)多種數(shù)據(jù)格式返回結(jié)果,我們都知道,一個完整的請求包含請求和處理請求以及結(jié)果返回三個步驟,在服務(wù)器端對請求處理完成以后,會將結(jié)果返回給客戶端,在gin框架中,支持返回多種請求數(shù)據(jù)格式,下面我們一起來看看2023-05-05