【Go】 http パッケージの Handle, Handler, HandleFunc, HanderFunc についての覚書

<font color="red">※注意: この記事ははあくまで個人学習用に整理しただけの記事で、内容としては不完全なものになります。読んでも参考にならない可能性が高いです。</font>

今まで JavaScript を書いていたが、Go 言語の学習を始めた。
golang の標準パッケージの、http パッケージの以下

- Handle
- Handler
- HandleFunc
- HanderFunc

の区別が全然ついていないので、自分の言葉でまとめようと思う。
理解しないまま書いていて、いつまで経っても覚えられないので、ちゃんと理解したい。

## http パッケージ

まず go doc の http パッケージについての説明を確認
https://godoc.org/net/http

>Package http provides HTTP client and server implementations.
http パッケージは、 HTTP クライアントとサーバーの実装を提供する。
Get, Head, Post, and PostForm make HTTP (or HTTPS) requests
Get、Head、Post、および PostForm は、 HTTP （or HTTPS ）リクエストを作成する

なるほど。

### func Handle
*https://godoc.org/net/http#Handle

```go
func Handle(pattern string, handler Handler)
```

>Handle registers the handler for the given pattern in the DefaultServeMux. 
Handleは、指定されたパターンのハンドラーを DefaultServeMux に登録する。 


なるほど。ハンドラーを DefaultServeMux へ登録しているとのこと。ServeMux と DefaultServeMux の違いは今度確認する。

### type Handler

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

Handler は ServeHTTP method を持った interface とのこと。

Interfaces in Go provide a way to specify the behavior of an object
Goのインターフェースは、オブジェクトの動作を指定する方法を提供するもの。

メソッドリストに持つ method 全てを持つ必要がある。

>A Handler responds to an HTTP request.
ハンドラーは、HTTP要求に応答する。

>ServeHTTP should write reply headers and data to the ResponseWriter and then return. Returning signals that the request is finished;
ServeHTTP は、応答ヘッダーとデータを ResponseWriter に書き込んでから返す必要がある。 戻り値は、要求が終了したことを示す。

>it is not valid to use the ResponseWriter or read from the Request.Body after or concurrently with the completion of the ServeHTTP call.
ServeHTTP呼び出しの完了後または完了と同時にResponseWriterを使用したり、Request.Bodyから読み取ることは無効。

とのこと。
メソッドリストに `ServeHTTP(ResponseWriter, *Request)` を持っており、ServeHTTP メソッドを持っている必要がある。

### func HandleFunc

```go
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
```

>HandleFunc registers the handler function for the given pattern in the DefaultServeMux.
HandleFuncは、指定されたパターンのハンドラー関数をDefaultServeMuxに登録する。

HandleFunc は関数で、第二引数に `func(ResponseWriter, *Request)` となっている。Handle 関数は第二引数が Handler interface になっていたので、その部分が異なる。

### type HandlerFunc

https://golang.org/src/net/http/server.go?h=HandlerFunc#L2034

```golang
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)

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

```

>The HandlerFunc type is an adapter to allow the use of ordinary functions as HTTP handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f.
HandlerFuncタイプは、通常の関数をHTTPハンドラーとして使用できるようにするアダプターです。 fが適切なシグネチャを持つ関数である場合、HandlerFunc（f）はfを呼び出すハンドラーです。

アダプター？

HandlerFunc 型は関数だが ServeHTTP method を持つ。ここ混乱ポイント。
go 言語は method を構造体型や構造体のポインタ型に定義できるのは知っていたが、interface 型でなければ、method を定義することができるらしい。

関数型が method を持つっていうのがイメージしにくい。。、




f が レシーバの HandlerFunc 型の関数で、それを実行しているだけ。
なぜこういう作りする必要があるのかを読み解かなければ。。。

まとめると

|name|種別|説明|
|-----|------|---|
|Handle|func|関数。第一引数に `patern string` 、第二引数に Handler 型を仮引数として受け取る。Handler は interface 型（抽象型 abstract type）で、これにより、ServeHTTP メソッドがあれば何でも受け取れる。|
|Handler|type interface|ServeHTTP 関数を持った interface。メソッドリストの ServeHTTP(ResponseWriter, *Request) メソッドを持つ必要あり|
|HandleFunc|func|関数。第一引数に `patern string` 、第二引数に `func(ResponseWriter, *Request)型` の関数を受け取る|
|HandlerFunc|type|関数型。 関数の型は `func(ResponseWriter, *Request)` 。そしてこの関数は ServeHTTP method を持つ|

となっている。