###HandleFunc
とHandle
の実行部分
注)実行したい関数、オブジェクトをhelloHandler
とする。
HandleFunc
の実行部分
http.HandleFunc("/hello", helloHandler)
Handle
の実行部分
http.Handle("/hello", &helloHandler{})
とても似ている!!!
なにが違うの??
###HandleFunc
とHandle
の違い
どちらも第1引数にはURLをとる。この二つには第2引数に違いがある。
HandleFunc
http.HandleFunc
は、第2引数にhttp.ResponseWriter
と*http.Request
を取る関数をそのまま渡せる。
Handle
HandleFunc関数
とは違い、Handle関数の第2引数
には関数を指定しない。Handle
ではhelloHandler型のServeHTTP関数
を定義したHandlerのポインタ
を指定する。
つまり、http.Handle
は、第2引数に***http.Handler
インタフェースを実装したオブジェクトを渡す。
ん?http.Handler
インタフェースを実装したオブジェクトって?
Handler
とはServeHTTP
という関数*を定義したインターフェイスのこと。参考:Handlerの公式ドキュメント
つまり、第2引数はServeHTTP(http.ResponseWriter, *http.Request)
という関数を実装したオブジェクトあれば良い。
func (t *helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { }
のようにhelloHandler
用にServeHTTP
を自分で実装する。
そうするとhelloHandler
はServeHTTPメソッド
を実装しているためhttp.Handler
インタフェースを実装したオブジェクトとなる。
###これまでのことも含め、何が起きているのかを見てみる
HandleFunc
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
-公式ドキュメントより参照
第1引数ではURLのパターンを受け取り、第2引数ではURLで実行したい関数を受け取る。
そしてDefaultServeMux.HandleFunc
に登録される。これはURLとHandler
の関連付けをおこなう役割を持つ。
DefaultServeMux
はグローバルなServeMuxのインスタンス
。net/http
パッケージにおいてあらかじめDefaultServeMux
が用意されている。
つまり、HandleFunc
では引数にURLと関数を渡すことで、それら二つを関連づけたものを登録してくれる。そして、URLにアクセスすると登録したところから探し出し、関数を実行してくれる。
Handle
func Handle(pattern string, handler Handler){
DefaultServeMux.HandleFunc(pattern, handler)
}
-公式ドキュメントより参照
第1引数ではHandleFunc
同様、URLのパターンを受け取る。第2引数ではURLで実行したい関数をServeHTTP関数
に定義したHandlerのポインタ
を受け取る。
そしてDefaultServeMux.HandleFunc
に登録される。
###HandleFunc
とHandle
の実装例
最後にHandleFunc
とHandle
の実装例を見てみる。
注)実行したい関数、オブジェクトをhelloHandler
とする。
HandleFunc
の実装例
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<h1>Hello, World</h1>") //「/hello」URLで実行したい処理
}
func main() {
http.HandleFunc("/hello", helloHandler)
http.ListenAndServe(":8080", nil)
}
このようにURLで実行したい関数を作成し、実行ではHandFunc関数
に引数としてURLと関数を渡す。
HandleFunc
の実装例
package main
import (
"fmt"
"net/http"
)
type helloHandler struct{}
func (*helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<h1>Hello, World</h1>") //「/hello」URLで実行したい処理
}
func main() {
http.Handle("/hello", &helloHandler{})
http.ListenAndServe(":8080", nil)
}
まずオブジェクトを作成し、URLで処理したい関数をServeHTTP
内に記述する。
このように、ServeHTTP関数
を定義したhelloHandler型
のHandler
(ServeHTTP
という関数を定義したインターフェイス)を作る。
実行では、http.Handle
にはURLとhttp.Handlerインタフェース
を実装したオブジェクト(helloHandler
)を引数として渡す。
###参考文献
Go言語の公式ドキュメント 「http.Handler」
Go言語の公式ドキュメント 「http.HandleFunc」
Go言語の公式ドキュメント 「http.Handle」