0
1

More than 5 years have passed since last update.

http.HandleFunc、http.HandlerFuncの違いをまとめてみた。

Posted at

前回の記事の続き。

http.Handlerとhttp.HandlerFuncの違いって何なんだよ

http.Handler:インターフェース(ResponseWriterと*Requestを引数に取るServeHttpメソッドさえあれば全部Handlerとして扱える!)

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

http.HandlerFunc:型(ResponseWriterと*Requestを引数に取るメソッドならなんでもHandlerFunc型)

server.go
type HandlerFunc func(ResponseWriter, *Request)

http.Handleとhttp.HandleFuncの違いって何なんだよ

http.Handle:メソッド(DefaultServeMux.Handleのラッピング)

server.go
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }

http.HandleFunc:メソッド(DefaultServeMux.HandleFuncのラッピング)

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

DefaultServeMux.HandleとDefaultServeMux.HandleFuncの違いって何なんだよ

DefaultServeMux.Handle:メソッド(パターン(URL)とHandlerを紐づける!)

server.go
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
    mux.mu.Lock()
    defer mux.mu.Unlock()

    if pattern == "" {
        panic("http: invalid pattern")
    }
    if handler == nil {
        panic("http: nil handler")
    }
    if _, exist := mux.m[pattern]; exist {
        panic("http: multiple registrations for " + pattern)
    }

    if mux.m == nil {
        mux.m = make(map[string]muxEntry)
    }
    e := muxEntry{h: handler, pattern: pattern}
    mux.m[pattern] = e
    if pattern[len(pattern)-1] == '/' {
        mux.es = appendSorted(mux.es, e)
    }

    if pattern[0] != '/' {
        mux.hosts = true
    }
}

DefaultServeMux.HandleFunc:DefaultServeMux.Handleを呼び出す。

server.go
// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    if handler == nil {
        panic("http: nil handler")
    }
    mux.Handle(pattern, HandlerFunc(handler))
}

結局、違いって何だったの?

http.Handleを呼び出すには、http.Handler(ServeHttpメソッドを持つインターフェース)が必要でした。
でも、http.HandleFuncを呼び出すには、インターフェースは不要で、単にResponseWriter, *Requestを引数に持つファンクションさえ渡せばよい。

つまり、実際にHandlerを登録する作業はhttp.Handleにhttp.Handler(インターフェース)を渡す必要があるけど、
プログラマが実際にハンドラを登録する時には、http.HandleFuncにhttp.HandleFunc(ファンクション)を渡せばよい。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1