日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
創(chuàng)新互聯(lián)GO教程:Go語(yǔ)言函數(shù)類型實(shí)現(xiàn)接口——把函數(shù)作為接口來(lái)調(diào)用

函數(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