`Handle`、`HandleFunc`、`Handler`、`HandlerFunc`についてまとめ

  • 32
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ただの勉強メモ程度ですが、httpパッケージ配下のHandleHandleFuncHandlerHandlerFuncについてまとめました。

Goでアプリケーションサーバを書くのはとても簡単で、そこらのLL並みの行数で小さなWebアプリケーションが立ち上がる。

httpd-sample.go
package main
import (
    "fmt"
    "log"
    "net/http"
)

func index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "hello, go httpd!")
}

func main() {
    http.HandleFunc("/", index)
    e := http.ListenAndServe(":8080", nil)

    if e != nil {
        log.Panic(e)
    }
}
$ go run ./httpd-sample.go

何のログも出ないですが、これで8080番をリスンするっぽい(logパッケージで細かく出してあげれば出る)。

流れは:

  • http.Handlehttp.HandleFunc でパスごとのハンドラーを指定する
  • http.ListenAndServe で立ち上がりる

便利簡単!

http.HandleFunchttp.ResponseWriter*http.Requestを取る関数をそのまま渡せる。

http.Handleは、http.Handlerインタフェースを実装したオブジェクトを渡す。要するにServeHTTP(http.ResponseWriter, *http.Request)という関数を実装したオブジェクトであれば良い。以下のような感じ:

httpd-sample2.go
package main
import (
    "fmt"
    "net/http"
)

type AppHandler struct {
    appName string
}

func(index *AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "hello, %s!", index.appName)
}

func main() {
    index := new(AppHandler)
    index.appName = "sample app"
    http.Handle("/", index)
    http.ListenAndServe(":8080", nil)
}

http.HandlerFuncというものもあり、これは関数を渡せばhttp.Handlerを実装したオブジェクトを返してくれる。

http.HandlerFuncは実際にはfunc(ResponseWriter, *Request)の別名だが、ServeHTTPをちゃんと実装している。ServeHTTPは自分自身をただ呼び出すだけである。簡潔。

type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

先ほどのHandleFuncも、実際は中でHandlerFuncを読んで変換している、と言う感じ。

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    mux.Handle(pattern, HandlerFunc(handler))
}

次は @hajimehoshi さんです

  • この記事は以下の記事からリンクされています
  • golangのお勉強2 からリンク