gorilla/mux
ルートおよびルータータイプに便利なutilメソッドを追加したい:
package util
import(
"net/http"
"github.com/0xor1/gorillaseed/src/server/lib/mux"
)
func (r *mux.Route) Subroute(tpl string, h http.Handler) *mux.Route{
return r.PathPrefix("/" + tpl).Subrouter().PathPrefix("/").Handler(h)
}
func (r *mux.Router) Subroute(tpl string, h http.Handler) *mux.Route{
return r.PathPrefix("/" + tpl).Subrouter().PathPrefix("/").Handler(h)
}
しかし、コンパイラは私に通知します
非ローカルタイプmux.Routerで新しいメソッドを定義できません
それでは、どうすればこれを達成できますか?匿名のmux.Routeフィールドとmux.Routerフィールドを持つ新しい構造体タイプを作成しますか?または、他の何か?
コンパイラが言及しているように、別のパッケージの既存の型を拡張することはできません。次のように、独自のエイリアスまたはサブパッケージを定義できます。
type MyRouter mux.Router
func (m *MyRouter) F() { ... }
または元のルーターを埋め込むことにより:
type MyRouter struct {
*mux.Router
}
func (m *MyRouter) F() { ... }
...
r := &MyRouter{router}
r.F()
@jimt here で与えられる答えを拡張したかった。その答えは正解であり、これを整理するのに非常に役立ちました。ただし、両方の方法(エイリアス、埋め込み)には注意が必要な点があります。
note:親と子という用語を使用しますが、それが作曲に最適かどうかはわかりません。基本的に、親はローカルで変更するタイプです。子は、その変更を実装しようとする新しいタイプです。
type child parent
// or
type MyThing imported.Thing
type child struct {
parent
}
// or with import and pointer
type MyThing struct {
*imported.Thing
}
これは次のコードで見ることができます。
package main
import (
"fmt"
)
type parent struct {
attr string
}
type childAlias parent
type childObjParent struct {
parent
}
type childPointerParent struct {
*parent
}
func (p *parent) parentDo(s string) { fmt.Println(s) }
func (c *childAlias) childAliasDo(s string) { fmt.Println(s) }
func (c *childObjParent) childObjParentDo(s string) { fmt.Println(s) }
func (c *childPointerParent) childPointerParentDo(s string) { fmt.Println(s) }
func main() {
p := &parent{"pAttr"}
c1 := &childAlias{"cAliasAttr"}
c2 := &childObjParent{}
// When the parent is a pointer it must be initialized.
// Otherwise, we get a nil pointer error when trying to set the attr.
c3 := &childPointerParent{}
c4 := &childPointerParent{&parent{}}
c2.attr = "cObjParentAttr"
// c3.attr = "cPointerParentAttr" // NOGO nil pointer dereference
c4.attr = "cPointerParentAttr"
// CAN do because we inherit parent's fields
fmt.Println(p.attr)
fmt.Println(c1.attr)
fmt.Println(c2.attr)
fmt.Println(c4.attr)
p.parentDo("called parentDo on parent")
c1.childAliasDo("called childAliasDo on ChildAlias")
c2.childObjParentDo("called childObjParentDo on ChildObjParent")
c3.childPointerParentDo("called childPointerParentDo on ChildPointerParent")
c4.childPointerParentDo("called childPointerParentDo on ChildPointerParent")
// CANNOT do because we don't inherit parent's methods
// c1.parentDo("called parentDo on childAlias") // NOGO c1.parentDo undefined
// CAN do because we inherit the parent's methods
c2.parentDo("called parentDo on childObjParent")
c3.parentDo("called parentDo on childPointerParent")
c4.parentDo("called parentDo on childPointerParent")
}