【Go】ServeMux と DefaultServeMux の違いについて

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

ServeMux と DefaultServeMux の違いについて、具体的に把握したい。

ServeMux については不完全な内容ながら以下にメモした。
[Go の ServeMux について](https://qiita.com/twinemarron/items/1c847501e0af8b35a93c)

### DefaultServeMux とは
公式ドキュメントには以下のようにコメントしてある。
https://golang.org/src/net/http/server.go?h=defaultServeMux#L2240

> DefaultServeMux is the default ServeMux used by Serve.
DefaultServeMuxは、Serveが使用するデフォルトのServeMuxです。

```golang
var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux
```

defaultServeMux は単なる変数名で、ServeMux 構造体のポインタが格納されている。

以下にはこのようにコメントがある
https://golang.org/src/net/http/server.go?h=defaultServeMux#L2527

```golang
// A Server defines parameters for running an HTTP server.
// The zero value for Server is a valid configuration.
type Server struct {
	Addr string

	Handler Handler // handler to invoke, http.DefaultServeMux if nil
```

> handler to invoke, http.DefaultServeMux if nil
呼び出すハンドラ。 nil の場合は http.DefaultServeMux

そして、その実装が以下

```golang
// serverHandler delegates to either the server's Handler or
// DefaultServeMux and also handles "OPTIONS *" requests.
type serverHandler struct {
	srv *Server
}

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
	handler := sh.srv.Handler
	if handler == nil {
		handler = DefaultServeMux // ここで DefaultServeMux が使用されている
	}
	if req.RequestURI == "*" && req.Method == "OPTIONS" {
		handler = globalOptionsHandler{}
	}
	handler.ServeHTTP(rw, req)
}
```

なるほど。結局 ServeMux と DefaultServeMux は同じ型だった。

ちなみに、上記の serverHander.ServeHTTP は以下で実行されている
https://golang.org/src/net/http/server.go?h=serve#L1925

```golang
func (c *conn) serve(ctx context.Context) {
	// 省略
	serverHandler{c.server}.ServeHTTP(w, w.req) // ここで実行
```

conn.serve は以下で実行されている
https://golang.org/src/net/http/server.go?h=serve#L2969

```golang
func (srv *Server) Serve(l net.Listener) error {
	// 省略
		go c.serve(connCtx) // ここで実行
```

Server.Serve は以下で実行されている
https://golang.org/src/net/http/server.go?h=serve#L2866

```golang
func (srv *Server) ListenAndServe() error {
	if srv.shuttingDown() {
		return ErrServerClosed
	}
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}
	ln, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}
	return srv.Serve(ln) // ここで実行
}
```

Server.ListenAndServe は直接実行する場合もあるし、http. ListenAndServe から実行されることもある。
http.ListenAndServe 内の　server.ListenAndServe 実行箇所は以下。
https://golang.org/src/net/http/server.go?h=serve#L3120

```golang
func ListenAndServe(addr string, handler Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe() // ここで実行
}
```

例えば、以下のようにサーバーを作成した場合、DefaultServeMux ではなく http.NewServeMux（） で作成した mux が使用されるが、

```golang
func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", index)
    server := &http.Server{
        Addr:           config.Address,
        Handler:        mux, // Handler に mux を設定した場合、DefaultServeMux ではなくこれが使用される
        ReadTimeout:    time.Duration(config.ReadTimeout * int64(time.Second)),
        WriteTimeout:   time.Duration(config.WriteTimeout * int64(time.Second)),
        MaxHeaderBytes: 1 << 20,
    }
    server.ListenAndServe()
}
```

以下のようにサーバーを作成した場合は、 DefaultServeMux が使用されるということか。

```golang
func main() {
    http.Handle("/", &templateHandler{filename: "index.html"})
    // この場合、マルチプレクサを特に設定していない事になるため、DefaultServeMux が使用される
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}
```

なるほど。一旦雑に理解。