最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang接口型函數(shù)使用小結(jié)

 更新時間:2022年06月20日 11:44:36   作者:周伯通之草堂筆記  
接口函數(shù)指的是用函數(shù)實現(xiàn)接口,這樣在調(diào)用的時候就會非常簡便,這種方式適用于只有一個函數(shù)的接口,這里以迭代一個map為例,演示這一實現(xiàn)的技巧,對Golang接口型函數(shù)使用知識感興趣的朋友一起看看吧

什么是接口型函數(shù)?顧名思義接口函數(shù)指的是用函數(shù)實現(xiàn)接口,這樣在調(diào)用的時候就會非常簡便,這種方式適用于只有一個函數(shù)的接口。

這里以迭代一個map為例,演示這一實現(xiàn)的技巧。

常規(guī)接口實現(xiàn)

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

  • 延遲函數(shù)的參數(shù)在defer語句出現(xiàn)時就已確定下來(傳值的就是當前值);
  • 延遲函數(shù)執(zhí)行按后進先出順序執(zhí)行;
  • 延遲函數(shù)可操作主函數(shù)的具名返回值(修改返回值);
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兩個參數(shù),這就是一個接口了,我們后面會實現(xiàn)他,具體做什么由我們的實現(xiàn)決定。

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

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

說得再多不如來點實際的例子:用我們剛剛定義的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["慕容復"] = "斗轉(zhuǎn)星移"
    var g greet = "諸位英雄"
    DoEach(persons, g)
}

輸出:

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

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

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

接口型函數(shù)出場

關于上面的實現(xiàn),我們可以發(fā)現(xiàn),有兩點不太好:

  • 因為必須要實現(xiàn)Handler接口,DoFunc這個方法名不能修改,不能定義一個更有意義的名字
  • 必須要新定義一個類型,才可以實現(xiàn)Handler接口,才能使用DoEach函數(shù)

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

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

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

我們改造下代碼如下:

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

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

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

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

完整代碼如下:

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["慕容復"] = "斗轉(zhuǎn)星移"
    var g greet = "諸位英雄"
    DoEach(persons, HandlerFunc(g.selfintroduction))
} 

輸出:

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

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

所以可以強制轉(zhuǎn)型。轉(zhuǎn)型后,因為HandlerFunc實現(xiàn)了Handler接口,所以我們就可以繼續(xù)使用原來的DoEach方法了。

進一步改造

現(xiàn)在解決了命名的問題,但是每次強制轉(zhuǎn)型是不是不太好?我們繼續(xù)重構(gòu)下,可以采用新定義一個函數(shù)的方式,幫助調(diào)用者強制轉(zhuǎn)型。

完整代碼如下:

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["慕容復"] = "斗轉(zhuǎn)星移"
    var g greet = "諸位英雄"
    EachFunc(persons, g.selfintroduction)
} 

上面我們新增了一個EachFunc函數(shù),幫助調(diào)用者強制轉(zhuǎn)型,調(diào)用者就不用自己做了。

現(xiàn)在我們發(fā)現(xiàn)EachFunc函數(shù)接收的是一個func(k, v interface{})類型的函數(shù),沒有必要實現(xiàn)原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["慕容復"] = "斗轉(zhuǎn)星移"
    EachFunc(persons, selfintroduction)
}

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

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)
}

這是一種非常好的技巧,提供兩種函數(shù),既可以以接口的方式使用,也可以以方法的方式,

對應我們例子中的DoEach和EachFunc這兩個函數(shù),靈活方便,也更符合自然語言規(guī)則吧。

無論從事什么行業(yè),只要做好兩件事就夠了,一個是你的專業(yè)、一個是你的人品,專業(yè)決定了你的存在,人品決定了你的人脈,剩下的就是堅持,用善良專業(yè)和真誠贏取更多的信任。

到此這篇關于Golang接口型函數(shù)使用技巧的文章就介紹到這了,更多相關Golang接口使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • go?mod?tidy報錯解決方法詳解

    go?mod?tidy報錯解決方法詳解

    這篇文章主要為大家介紹了go?mod?tidy報錯解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Golang Copier入門到入坑探究

    Golang Copier入門到入坑探究

    這篇文章主要為大家介紹了Golang Copier入門到入坑探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Go在GoLand中引用github.com中的第三方包具體步驟

    Go在GoLand中引用github.com中的第三方包具體步驟

    這篇文章主要給大家介紹了關于Go在GoLand中引用github.com中第三方包的具體步驟,文中通過圖文介紹的非常詳細,對大家學習或者使用Go具有一定的參考價值,需要的朋友可以參考下
    2024-01-01
  • go進行http請求偶發(fā)EOF問題分析

    go進行http請求偶發(fā)EOF問題分析

    go使用連接池進行http請求,一般都能請求成功,但偶然會出現(xiàn)請求失敗返回EOF錯誤的情況,本文主要來帶大家分析一下為什么會出現(xiàn)這樣的問題并提供解決方法,需要的可以參考下
    2025-01-01
  • 深入淺析Go中三個點(...)用法

    深入淺析Go中三個點(...)用法

    這篇文章主要介紹了深入淺析Go中三個點(...)用法,需要的朋友可以參考下
    2021-10-10
  • Go語言中的Slice學習總結(jié)

    Go語言中的Slice學習總結(jié)

    這篇文章主要介紹了Go語言中的Slice學習總結(jié),本文講解了Slice的定義、Slice的長度和容量、Slice是引用類型、Slice引用傳遞發(fā)生“意外”等內(nèi)容,需要的朋友可以參考下
    2014-11-11
  • Go語言中的流程控制結(jié)構(gòu)和函數(shù)詳解

    Go語言中的流程控制結(jié)構(gòu)和函數(shù)詳解

    這篇文章主要介紹了Go語言中的流程控制結(jié)構(gòu)和函數(shù)詳解,本文詳細講解了if、goto、for、switch等控制語句,同時對函數(shù)相關知識做了講解,需要的朋友可以參考下
    2014-10-10
  • 一文帶你掌握Golang中的值類型和引用類型

    一文帶你掌握Golang中的值類型和引用類型

    在?Golang?中,數(shù)據(jù)類型可以分為兩大類:值類型(Value?Types)和引用類型(Reference?Types),理解這兩種類型的區(qū)別對于理解?Golang?中的數(shù)據(jù)傳遞和內(nèi)存管理是很重要的,下面就跟隨小編一起深入了解一下它們吧
    2024-01-01
  • Golang中多個if代碼優(yōu)化小技巧

    Golang中多個if代碼優(yōu)化小技巧

    這篇文章主要為大家詳細介紹了Golang中一些常用的if代碼優(yōu)化小技巧,w文中的示例代碼簡潔易懂,具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-10-10
  • golang自帶的死鎖檢測并非銀彈的問題小結(jié)

    golang自帶的死鎖檢測并非銀彈的問題小結(jié)

    Go語言自帶的死鎖檢測機制并不萬能,它只對用戶創(chuàng)建的協(xié)程進行檢測,并且在特定條件下可能會“失靈”,死鎖檢測的觸發(fā)時機和檢測內(nèi)容也有限制,因此不能完全避免死鎖問題,為了預防死鎖,應該在編寫代碼時提前進行設計和測試,感興趣的朋友跟隨小編一起看看吧
    2025-01-01

最新評論

孝义市| 班玛县| 郯城县| 定日县| 丰顺县| 乐业县| 二手房| 常宁市| 敖汉旗| 彝良县| 边坝县| 靖江市| 蓬溪县| 邢台县| 新乡市| 通海县| 兖州市| 阿拉尔市| 教育| 合川市| 扬中市| 桃江县| 朔州市| 开鲁县| 开原市| 修武县| 枝江市| 绥阳县| 高陵县| 丰台区| 石林| 武夷山市| 日喀则市| 宿迁市| 招远市| 毕节市| 黔江区| 海丰县| 吉林市| 达日县| 丰城市|