ポインタ
ポインタとかアドレスとか調べてわかった気にはなったけど実際のコード見てもよくわからん!!となったので自分なりに簡単にメモします。
使用例
type Server struct {
srv *http.Server
l net.Listener
}
func NewServer(l net.Listener, mux http.Handler) *Server {
return &Server{
srv: &http.Server{Handler: mux},
l: l,
}
}
例えばこういうNewなんちゃらで新しい構造体を生成する関数をよく見ます。
Server構造体
Server
構造体のsrv
にはポインタが使われていて、l
には使われていません。
理由はhttp.Server
は
type Server struct {
Addr string
Handler Handler
// 以下略
}
というような構造体なのに対して、net.Listener
は
type Listener interface {
Accept() (Conn, error)
Close() error
Addr() Addr
}
というインターフェースです。Go言語では、インターフェースの変数は、そのインターフェースを実装する任意の型の値を保持することができ、それ自体がポインタのように振る舞います。
逆にいうと、構造体は、そのポインタを取得し、それを通じて構造体の内容を変更することができます。今回の例では、Server
構造体のsrv
を好きに変更できる、みたいなイメージです。
NewServer関数
func NewServer(l net.Listener, mux http.Handler) *Server {
return &Server{
srv: &http.Server{Handler: mux},
l: l,
}
}
これは、returnで返される構造体にポインタがついています。(&Server{}
とすることでポインタを生成できます)
こうすることで、Newで生成されたサーバーの変数を自在に変更できるようになります。Newという名前の通り、大元の情報から新しく構造体を作れる(当然大元の情報は変更できない)みたいな感じです。
ここでServer
を返してしまうと、他の場所で参照し、その状態を変更することができません。