GO語言中接口和接口型函數(shù)的具體使用
前言
今天在編碼中,看到了一個非常經(jīng)典的接口用法如下,于是查閱了相關資料,發(fā)現(xiàn)此種寫法為接口型函數(shù),本文對此做了細致的闡述。
// A Getter loads data for a key.
type Getter interface {
?? ?Get(key string) ([]byte, error)
}
// A GetterFunc implements Getter with a function.
type GetterFunc func(key string) ([]byte, error)
// Get implements Getter interface function
func (f GetterFunc) Get(key string) ([]byte, error) {
?? ?return f(key)
}GO語言中的接口怎么用?
以上的例程中,首先定義了一個接口,隨后定義了一個函數(shù)類型實現(xiàn)了此接口,那么GO語言中的接口到底怎么使用呢?
在GO語言中,接口是一種類型,它定義了一組方法的組合,但沒有具體的代碼實現(xiàn),接口定義示例如下:
type MyInterface interface {
Method1() string
Method2(int) int
}
GO語言中,接口的實現(xiàn)是隱式的。接口實現(xiàn)要綁定在一個類型上面,通過實現(xiàn)類型的方法,來隱式的實現(xiàn)接口,實現(xiàn)示例如下:
type MyType struct {
? ? // type fields
}
func (t *MyType) Method1() string {
? ? return "Hello, world!"
}
func (t *MyType) Method2(n int) int {
? ? return n * n
}實現(xiàn)接口后,我們可以把接口作為參數(shù)傳入某個函數(shù)中,這樣實現(xiàn)了接口的不同數(shù)據(jù)結(jié)構就可以都作為接口傳入函數(shù)中了:
func MyFunction(i MyInterface) {
fmt.Println(i.Method1())
fmt.Println(i.Method2(8))
}
調(diào)用此函數(shù)時,就可以先聲明實現(xiàn)了此接口的數(shù)據(jù)結(jié)構,然后調(diào)用函數(shù)即可:
func main() {
t := &MyType{}
MyFunction(t)
}
調(diào)用后即可產(chǎn)生結(jié)果:
Hello, world!
64
使用函數(shù)類型實現(xiàn)接口有何好處?
以上是使用的結(jié)構體隱式實現(xiàn)了接口,還可以自定義函數(shù)類型來隱式實現(xiàn)接口。這樣可以使用匿名函數(shù)或者普通函數(shù)(都需要類型轉(zhuǎn)換)直接作為接口參數(shù)傳入函數(shù)中。接口及實現(xiàn)如下:
type MyInterface interface {
?? ?Method1() string
}
type MyInterfaceFunc func()string
func (f MyInterfaceFunc) Method1()string {
?? ?return f()
}定義一個以接口為參數(shù)的函數(shù):
func MyFunction(i MyInterfaceFunc){
fmt.Println(i.Method1())
}
使用普通函數(shù)進行調(diào)用:
func Dog()string{
? ?return "dog dog !"
}
func main() {
? ?MyFunction(MyInterfaceFunc(Dog))
}使用匿名函數(shù)進行調(diào)用:
func main() {
MyFunction(MyInterfaceFunc(func() string {
return "hello!"
}))
}
可以看到,最終的輸出都是正確的:
dog dog !
hello!
總的來說,大大的增加了代碼的可擴展性,如果沒有接口型函數(shù)的話,那么想要實現(xiàn)一個新的函數(shù),就需要聲明新的類型(如結(jié)構體),再隱式的實現(xiàn)接口,再傳入MyFunction函數(shù)中。有了接口型函數(shù)后,那么只需要實現(xiàn)核心邏輯,隨后將函數(shù)轉(zhuǎn)換為預期的類型即可直接傳入。
GO源碼例子
net/http 的 Handler 和 HandlerFunc 就是一個典型的接口型函數(shù)的例子,Handler的定義如下:
type Handler interface {
?? ?ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
?? ?f(w, r)
}可以使用http.Handle來對經(jīng)典的映射路徑和處理函數(shù)進行映射:
func Handle(pattern string, handler Handler)
觀察這個函數(shù),可以發(fā)現(xiàn)跟上文的例子很類似,這里的handler就是接口類型,然后在HandlerFunc的基礎上做了實現(xiàn),那么我們可以進行如下的使用:
func home(w http.ResponseWriter, r *http.Request) {
?? ?w.WriteHeader(http.StatusOK)
?? ?_, _ = w.Write([]byte("hello, index page"))
}
func main() {
?? ?http.Handle("/home", http.HandlerFunc(home))
?? ?_ = http.ListenAndServe("localhost:8000", nil)
}運行起來后,就會監(jiān)聽localhost:8000并運行home函數(shù)。這里將home進行類型轉(zhuǎn)換為http.HandlerFunc再作為接口類型傳入http.Handle,非常的方便。
我們同樣可以使用匿名函數(shù)的形式:
func main() {
http.Handle("/home", http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
writer.Write([]byte("hello word!"))
}))
_ = http.ListenAndServe("localhost:8000", nil)
}
可以達到同樣的效果。
到此這篇關于GO語言中接口和接口型函數(shù)的具體使用的文章就介紹到這了,更多相關GO語言接口和接口型函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Mac上Go環(huán)境和VS Code的正確安裝與配置方法
Go語言是一個新興的語言。下面介紹一下如何在Mac系統(tǒng)下安裝和使用這個語言,Go語言提供了mac下安裝包,可直接下載安裝包點擊安裝2018-03-03

