91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang接口型函數如何使用

發布時間:2022-06-20 15:15:11 來源:億速云 閱讀:130 作者:iii 欄目:開發技術

這篇文章主要介紹“Golang接口型函數如何使用”,在日常操作中,相信很多人在Golang接口型函數如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Golang接口型函數如何使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

常規接口實現

defer語句用于延遲函數調用,每次會把一個函數壓入棧中,函數返回前再把延遲的函數取出并執行。延遲函數可以有參數:

  • 延遲函數的參數在defer語句出現時就已確定下來(傳值的就是當前值);

  • 延遲函數執行按后進先出順序執行;

  • 延遲函數可操作主函數的具名返回值(修改返回值);

type Handler interface {
    DoFunc(k, v interface{})
}
func DoEach(m map[interface{}]interface{}, h Handler) {
    if m != nil && len(m) > 0 {
        for k, v := range m {
            h.DoFunc(k, v)
        }
    }
}

這里我們定義了一個Handler接口,只有一個DoFunc方法,接收k,v兩個參數,這就是一個接口了,我們后面會實現他,具體做什么由我們的實現決定。

然后我們定義了一個DoEach函數,該函數的功能就是迭代傳遞過來的map參數,然后把map的每個key和value值傳遞給Handler的DoFunc方法,

具體由這個Handler的實現來決定,這也是面向接口編程。

說得再多不如來點實際的例子:用我們剛剛定義的DoEach方法和Handler接口。

package main
import "fmt"
type Handler interface {
    DoFunc(k, v interface{})
}
func DoEach(m map[interface{}]interface{}, h Handler) {
    if m != nil && len(m) > 0 {
        for k, v := range m {
            h.DoFunc(k, v)
        }
    }
}
type greet string
func ( g greet) DoFunc(k, v interface{}) {
    fmt.Printf("%s,在下%s,我的必殺技是%s\n", g, k, v)
}
func main() {
    persons := make(map[interface{}]interface{})
    persons["喬峰"] = "龍爪手"
    persons["鳩摩智"] = "小無相功"
    persons["慕容復"] = "斗轉星移"
    var g greet = "諸位英雄"
    DoEach(persons, g)
}

輸出:

諸位英雄,在下喬峰,我的必殺技是龍爪手
諸位英雄,在下鳩摩智,我的必殺技是小無相功
諸位英雄,在下慕容復,我的必殺技是斗轉星移

以上實現,我們定義了一個map來存儲幾位大佬,map的key是大佬的名字,value是該大佬的絕技。greet是我們新定義的類型,

其對應基本類型string,該greet實現了Handler接口,打印出自我介紹的信息。

接口型函數出場

關于上面的實現,我們可以發現,有兩點不太好:

  • 因為必須要實現Handler接口,DoFunc這個方法名不能修改,不能定義一個更有意義的名字

  • 必須要新定義一個類型,才可以實現Handler接口,才能使用DoEach函數

首先我們先解決第一個問題,根據我們具體做的事情定義一個更有意義的方法名,比如例子中是自我介紹,

那么我們使用selfintroduction是不是要比DoFunc這個語義的方法要好呢。

如果調用者改了方法名,那么就不能實現Handler接口,還要使用DoEach方法怎么辦?那就是由提供DoEach函數的負責提供Handler的實現,

我們改造下代碼如下:

type HandlerFunc func(k, v interface{})
 
func (f HandlerFunc) DoFunc(k, v interface{}) {
    f(k, v)
}

上面代碼我們定義了一個新的類型HandlerFunc,它是一個func(k, v interface{})類型,然后這個新的HandlerFunc實現了Handler接口(原始實現方式中的

type Handler interface { DoFunc(k, v interface{}) }

),DoFunc方法的實現是調用HandlerFunc本身,因為HandlerFunc類型的變量就是一個方法。現在我們使用這種方式實現同樣的效果。

完整代碼如下:

package main
import "fmt"
type Handler interface {
    DoFunc(k, v interface{})
}
type HandlerFunc func(k, v interface{})
func (f HandlerFunc) DoFunc(k, v interface{}) {
    f(k, v)
}
type greet string
func (g greet) selfintroduction(k, v interface{}) {
    fmt.Printf("%s,在下%s,我的必殺技是%s\n", g, k, v)
}
func DoEach(m map[interface{}]interface{}, h Handler) {
    if m != nil && len(m) > 0 {
        for k, v := range m {
            h.DoFunc(k, v)
        }
    }
}
func main() {
    persons := make(map[interface{}]interface{})
    persons["喬峰"] = "龍爪手"
    persons["鳩摩智"] = "小無相功"
    persons["慕容復"] = "斗轉星移"
    var g greet = "諸位英雄"
    DoEach(persons, HandlerFunc(g.selfintroduction))
} 

輸出:

諸位英雄,在下喬峰,我的必殺技是龍爪手
諸位英雄,在下鳩摩智,我的必殺技是小無相功
諸位英雄,在下慕容復,我的必殺技是斗轉星移

還是差不多原來的實現,只是把原接口方法名DoFunc改為selfintroduction。HandlerFunc(g.selfintroduction)不是方法的調用,而是轉型,因為selfintroduction和HandlerFunc是同一種類型,

所以可以強制轉型。轉型后,因為HandlerFunc實現了Handler接口,所以我們就可以繼續使用原來的DoEach方法了。

進一步改造

現在解決了命名的問題,但是每次強制轉型是不是不太好?我們繼續重構下,可以采用新定義一個函數的方式,幫助調用者強制轉型。

完整代碼如下:

package main
import "fmt"
type Handler interface {
    DoFunc(k, v interface{})
}
type HandlerFunc func(k, v interface{})
func (f HandlerFunc) DoFunc(k, v interface{}) {
    f(k, v)
}
type greet string
func (g greet) selfintroduction(k, v interface{}) {
    fmt.Printf("%s,在下%s,我的必殺技是%s\n", g, k, v)
}
func DoEach(m map[interface{}]interface{}, h Handler) {
    if m != nil && len(m) > 0 {
        for k, v := range m {
            h.DoFunc(k, v)
        }
    }
}
func EachFunc(m map[interface{}]interface{}, f func(k, v interface{})) {
    DoEach(m, HandlerFunc(f))
}
func main() {
    persons := make(map[interface{}]interface{})
    persons["喬峰"] = "龍爪手"
    persons["鳩摩智"] = "小無相功"
    persons["慕容復"] = "斗轉星移"
    var g greet = "諸位英雄"
    EachFunc(persons, g.selfintroduction)
} 

上面我們新增了一個EachFunc函數,幫助調用者強制轉型,調用者就不用自己做了。

現在我們發現EachFunc函數接收的是一個func(k, v interface{})類型的函數,沒有必要實現原Handler接口了,所以我們新的類型可以去掉不用了。

去掉了自定義類型greet之后,整個代碼更簡潔,可讀性是不是更好點?簡潔干凈的完整代碼如下:

package main
import "fmt"
type Handler interface {
    DoFunc(k, v interface{})
}
type HandlerFunc func(k, v interface{})
func (f HandlerFunc) DoFunc(k, v interface{}) {
    f(k, v)
}
func DoEach(m map[interface{}]interface{}, h Handler) {
    if m != nil && len(m) > 0 {
        for k, v := range m {
            h.DoFunc(k, v)
        }
    }
}
func EachFunc(m map[interface{}]interface{}, f func(k, v interface{})) {
    DoEach(m, HandlerFunc(f))
}
func selfintroduction(k, v interface{}) {
    fmt.Printf("諸位英雄,在下%s,我的必殺技是%s\n", k, v)
}
func main() {
    persons := make(map[interface{}]interface{})
    persons["喬峰"] = "龍爪手"
    persons["鳩摩智"] = "小無相功"
    persons["慕容復"] = "斗轉星移"
    EachFunc(persons, selfintroduction)
}

以上關于函數型接口就寫完了,如果大家仔細留意,發現和我們自己平時使用的http.Handle方法非常類似,其實接口http.Handler就是這么實現的。

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}
 
func Handle(pattern string, handler Handler) {
    DefaultServeMux.Handle(pattern, handler)
}
 
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}

到此,關于“Golang接口型函數如何使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石首市| 九江县| 长武县| 黄陵县| 秦安县| 吉木乃县| 麻栗坡县| 沧州市| 平罗县| 黄平县| 同德县| 孝感市| 印江| 蒲江县| 兴和县| 宁南县| 明水县| 从江县| 林西县| 宁津县| 岫岩| 凌海市| 林州市| 育儿| 五大连池市| 图们市| 西和县| 陇南市| 科尔| 恩平市| 固始县| 揭东县| 电白县| 福建省| 德兴市| 长丰县| 家居| 天全县| 高青县| 五河县| 桐梓县|