Suppose you have the following code: Isn't it the same thing that both are doing? As a result of my investigation.
http.Handle("/any/", anyHandler)
http.ListenAndServe(":8080", nil)
mux := http.NewServeMux()
mux.Handle("/any/", anyHandler)
http.ListenAndServe(":8080", mux)
Both were basically doing the same thing internally.
http.Handle() The URL pattern and the corresponding handler are registered in DefaultServeMux.
The implementation is as follows.
// Handle registers the handler for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
DefaultServeMux
is a variable that stores the pointer type of ServeMux.
HTTP multiplexer. The implementation is as follows.
type ServeMux struct {
mu sync.RWMutex
m map[string]muxEntry
es []muxEntry // slice of entries sorted from longest to shortest.
hosts bool // whether any patterns contain hostnames
}
The URL pattern and the corresponding handler are registered in DefaultServeMux.
That is, the part of DefaultServeMux.Handle (pattern, handler)
.
A handler corresponding to the URL pattern is added to ServeMux.m
.
The implementation is as follows.
// 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
}
}
http.NewServeMux().Handle() The URL pattern and the corresponding handler are registered in ServeMux. The implementation is as follows.
// 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
}
}
Isn't it exactly the same process as DefaultServeMux.Handle (pattern, handler)
? ..
In other words, it internally performs the same processing as http.Handle ()
.
The code at the beginning can do exactly the same thing.
However, since http.NewServeMux (). Handle ()
creates ServeMux by itself
It may be used when you want to change the value in it independently.
Recommended Posts