新聞中心
函數(shù)和其他類型一樣都屬于“一等公民”,其他類型能夠?qū)崿F(xiàn)接口,函數(shù)也可以,本節(jié)將對(duì)結(jié)構(gòu)體與函數(shù)實(shí)現(xiàn)接口的過程進(jìn)行對(duì)比。

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括白堿灘網(wǎng)站建設(shè)、白堿灘網(wǎng)站制作、白堿灘網(wǎng)頁(yè)制作以及白堿灘網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,白堿灘網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到白堿灘省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
首先給出本節(jié)完整的代碼:
package main
import (
"fmt"
)
// 調(diào)用器接口
type Invoker interface {
// 需要實(shí)現(xiàn)一個(gè)Call方法
Call(interface{})
}
// 結(jié)構(gòu)體類型
type Struct struct {
}
// 實(shí)現(xiàn)Invoker的Call
func (s *Struct) Call(p interface{}) {
fmt.Println("from struct", p)
}
// 函數(shù)定義為類型
type FuncCaller func(interface{})
// 實(shí)現(xiàn)Invoker的Call
func (f FuncCaller) Call(p interface{}) {
// 調(diào)用f函數(shù)本體
f(p)
}
func main() {
// 聲明接口變量
var invoker Invoker
// 實(shí)例化結(jié)構(gòu)體
s := new(Struct)
// 將實(shí)例化的結(jié)構(gòu)體賦值到接口
invoker = s
// 使用接口調(diào)用實(shí)例化結(jié)構(gòu)體的方法Struct.Call
invoker.Call("hello")
// 將匿名函數(shù)轉(zhuǎn)為FuncCaller類型,再賦值給接口
invoker = FuncCaller(func(v interface{}) {
fmt.Println("from function", v)
})
// 使用接口調(diào)用FuncCaller.Call,內(nèi)部會(huì)調(diào)用函數(shù)本體
invoker.Call("hello")
}有如下一個(gè)接口:
// 調(diào)用器接口
type Invoker interface {
// 需要實(shí)現(xiàn)一個(gè)Call()方法
Call(interface{})
}這個(gè)接口需要實(shí)現(xiàn) Call() 方法,調(diào)用時(shí)會(huì)傳入一個(gè) interface{} 類型的變量,這種類型的變量表示任意類型的值。
接下來(lái),使用結(jié)構(gòu)體進(jìn)行接口實(shí)現(xiàn)。
結(jié)構(gòu)體實(shí)現(xiàn)接口
結(jié)構(gòu)體實(shí)現(xiàn) Invoker 接口的代碼如下:
// 結(jié)構(gòu)體類型
type Struct struct {
}
// 實(shí)現(xiàn)Invoker的Call
func (s *Struct) Call(p interface{}) {
fmt.Println("from struct", p)
}代碼說明如下:
- 第 2 行,定義結(jié)構(gòu)體,該例子中的結(jié)構(gòu)體無(wú)須任何成員,主要展示實(shí)現(xiàn) Invoker 的方法。
- 第 6 行,Call() 為結(jié)構(gòu)體的方法,該方法的功能是打印 from struct 和傳入的 interface{} 類型的值。
將定義的 Struct 類型實(shí)例化,并傳入接口中進(jìn)行調(diào)用,代碼如下:
// 聲明接口變量
var invoker Invoker
// 實(shí)例化結(jié)構(gòu)體
s := new(Struct)
// 將實(shí)例化的結(jié)構(gòu)體賦值到接口
invoker = s
// 使用接口調(diào)用實(shí)例化結(jié)構(gòu)體的方法Struct.Call
invoker.Call("hello")代碼說明如下:
- 第 2 行,聲明 Invoker 類型的變量。
- 第 5 行,使用 new 將結(jié)構(gòu)體實(shí)例化,此行也可以寫為 s:=&Struct。
- 第 8 行,s 類型為 *Struct,已經(jīng)實(shí)現(xiàn)了 Invoker 接口類型,因此賦值給 invoker 時(shí)是成功的。
- 第 11 行,通過接口的 Call() 方法,傳入 hello,此時(shí)將調(diào)用 Struct 結(jié)構(gòu)體的 Call() 方法。
接下來(lái),對(duì)比下函數(shù)實(shí)現(xiàn)結(jié)構(gòu)體的差異。
代碼輸出如下:
from struct hello
函數(shù)體實(shí)現(xiàn)接口
函數(shù)的聲明不能直接實(shí)現(xiàn)接口,需要將函數(shù)定義為類型后,使用類型實(shí)現(xiàn)結(jié)構(gòu)體,當(dāng)類型方法被調(diào)用時(shí),還需要調(diào)用函數(shù)本體。
// 函數(shù)定義為類型
type FuncCaller func(interface{})
// 實(shí)現(xiàn)Invoker的Call
func (f FuncCaller) Call(p interface{}) {
// 調(diào)用f()函數(shù)本體
f(p)
}代碼說明如下:
- 第 2 行,將 func(interface{}) 定義為 FuncCaller 類型。
- 第 5 行,F(xiàn)uncCaller 的 Call() 方法將實(shí)現(xiàn) Invoker 的 Call() 方法。
- 第 8 行,F(xiàn)uncCaller 的 Call() 方法被調(diào)用與 func(interface{}) 無(wú)關(guān),還需要手動(dòng)調(diào)用函數(shù)本體。
上面代碼只是定義了函數(shù)類型,需要函數(shù)本身進(jìn)行邏輯處理,F(xiàn)uncCaller 無(wú)須被實(shí)例化,只需要將函數(shù)轉(zhuǎn)換為 FuncCaller 類型即可,函數(shù)來(lái)源可以是命名函數(shù)、匿名函數(shù)或閉包,參見下面代碼:
// 聲明接口變量
var invoker Invoker
// 將匿名函數(shù)轉(zhuǎn)為FuncCaller類型, 再賦值給接口
invoker = FuncCaller(func(v interface{}) {
fmt.Println("from function", v)
})
// 使用接口調(diào)用FuncCaller.Call, 內(nèi)部會(huì)調(diào)用函數(shù)本體
invoker.Call("hello")代碼說明如下:
- 第 2 行,聲明接口變量。
- 第 5 行,將 func(v interface{}){} 匿名函數(shù)轉(zhuǎn)換為 FuncCaller 類型(函數(shù)簽名才能轉(zhuǎn)換),此時(shí) FuncCaller 類型實(shí)現(xiàn)了 Invoker 的 Call() 方法,賦值給 invoker 接口是成功的。
- 第 10 行,使用接口方法調(diào)用。
代碼輸出如下:
from function hello
HTTP包中的例子
HTTP 包中包含有 Handler 接口定義,代碼如下:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}Handler 用于定義每個(gè) HTTP 的請(qǐng)求和響應(yīng)的處理過程。
同時(shí),也可以使用處理函數(shù)實(shí)現(xiàn)接口,定義如下:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}要使用閉包實(shí)現(xiàn)默認(rèn)的 HTTP 請(qǐng)求處理,可以使用 http.HandleFunc() 函數(shù),函數(shù)定義如下:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}而 DefaultServeMux 是 ServeMux 結(jié)構(gòu),擁有 HandleFunc() 方法,定義如下:
func (mux *ServeMux) HandleFunc(pattern string, handler func
(ResponseWriter, *Request)) {
mux.Handle(pattern, HandlerFunc(handler))
}上面代碼將外部傳入的函數(shù) handler() 轉(zhuǎn)為 HandlerFunc 類型,HandlerFunc 類型實(shí)現(xiàn)了 Handler 的 ServeHTTP 方法,底層可以同時(shí)使用各種類型來(lái)實(shí)現(xiàn) Handler 接口進(jìn)行處理。
新聞標(biāo)題:創(chuàng)新互聯(lián)GO教程:Go語(yǔ)言函數(shù)類型實(shí)現(xiàn)接口——把函數(shù)作為接口來(lái)調(diào)用
當(dāng)前地址:http://www.dlmjj.cn/article/cdjhjoc.html


咨詢
建站咨詢
