go type func() 自定義函數類型


@

目錄

    因看不懂 go 中的自定義函數類型,看了https://www.jianshu.com/p/431abe0d2ed5 理解了不少,特此搬運到自己博客

    在看golang 的http服務部分代碼時,被golang 中的 type func()寫法難住了,一時沒看懂代碼。后來查資料后,有了一點理解。
    在golang中可以通過這樣簡單實現一個http服務

    package main
    
    import "net/http"
    
    func mHttp() {
        http.HandleFunc("/", h)
        http.ListenAndServe("0.0.0.0:8888",nil)
    }
    func h(w http.ResponseWriter, r *http.Request) {
    
    }
    

    http.HandleFunc()是一個注冊函數,傳一個string類型的路由,和一個函數,函數的參數為(http.ResponseWriter, *http.Request)。跟蹤進入函數,在golang 源碼net/http/server.go文件中

    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }
    

    在HandleFunc調用了DefaultServeMux.HandleFunc(pattern, handler)
    至於這些函數是干啥的先不做探討,這不是本文的重點。
    再次跟進函數

    func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        if handler == nil {
            panic("http: nil handler")
        }
        mux.Handle(pattern, HandlerFunc(handler))
    }
    

    在mux.Handle(pattern, HandlerFunc(handler)) 的第二個參數HandlerFunc(handler)是什么鬼。
    跟進看一下

    type HandlerFunc func(ResponseWriter, *Request)
    
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
    }
    

    原來HandlerFunc 是用 type 定義的函數,而函數的類型就是最開始傳入的類型
    func(ResponseWriter, *Request)
    ServeHTTP是HandlerFunc的一個方法(注意一下,golang中方法和函數不是一回事)。並且HandlerFunc實現了 Handler接口
    Handler接口定義:

    type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
    }
    

    回到HandleFunc方法中,mux.Handle(pattern, HandlerFunc(handler))的第二個參數是把傳入的函數 handler 強轉成 HandlerFunc類型,這樣handler就實現了Handler接口。
    到這我們明白HandlerFunc(handler) 是把普通函數強轉成type定義的函數。
    現在寫一個簡單的demo驗證一下:

    package main
    
    import "fmt"
    
    func main() {
    	one(2,callback)
    }
    
    //需要傳遞函數
    func callback(i int) {
    	fmt.Println("i am callBack")
    	fmt.Println(i)
    }
    
    //main 中調用的函數
    func one(i int,f func(int)) {
    	two(i,fun(f))
    }
    
    //one() 中調用的函數
    func two(i int, c Call) {
    	c.call(i)
    }
    //定義的type函數
    type fun func(int)
    
    //fun實現的Call接口的call()函數
    func (f fun) call(i int) {
    	f(i)
    }
    
    //接口
    type Call interface {
    	call(int)
    }
    

    先看一下程序的運行結果:
    在這里插入圖片描述
    我們在main()函數中調用了one()函數,並傳入了callback()函數,最終調用了我們傳入的callback()函數。
    理一下思路:
    使用type定義函數 func(int)
    定義 Call 接口,Call中有一個函數 call(int)
    在main()中調用one(2, callback),在one()中調用two(),傳入two()函數前,對callback函數實現了類型轉換,從普通函數轉換成type定義的函數。
    在 two() 中調用傳入的 c 因為 c 實現了 Call 接口,所以可以調用 call() 函數,最終調用了我們傳入的 callback() 函數。


    免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM