我目前正处于编写实用程序库的设计阶段,该库将与x-go-binding进行交互。容易一点。 (我之前已经使用 Python 和 xpyb 完成了此操作。)例如,它将有助于查询 EWMH spec 中定义的信息。并将键绑定(bind)到回调函数。 (还有更多。)因此,作为我对包布局的最初想法,请考虑:
- xutil
- 嗯嗯
- 按键绑定(bind)
其中每个都是它自己的包。 (与标准库的镜像包设置类似。)
我的情况的独特之处在于,几乎每个 x-go-binding 调用都需要 xgb 连接对象或根窗口标识符的某种组合。因此,对我来说,将这些信息存储在如下结构中是有意义的:
type XUtilConnection struct {
conn xgb.Conn
root xgb.Id
// a few other things, like a mapping of events to callbacks
}
这样我就有一个可以像这样使用的工厂:
xconn = xutil.NewXUtilConnection(blah blah)
它可以这样使用:
xconn.get_active_window()
xconn.bind_key("Shift-a", my_callback_fun)
还可能有如下功能:
keybind.get_keycode("a")
ewmh.get_atom("_NET_ACTIVE_WINDOW")
我的问题当然是,据我所知,接收器只能是在同一包中声明的类型。如果我分离我的包,我就无法在任何子包中使用我的 XUtilConnection 类型作为接收器。
我怀疑我的答案是将这个大包分成不同的逻辑文件,但我担心这可能会导致命名空间困惑。 (例如,实现 EWMH 规范可能需要 100 多个函数。)
我还知道我可以在 XUtilConnection 对象的每个子包中定义一个新的容器类型。 (我听说这应该是一个包含单个成员 XUtilConnection 的结构,以避免强制转换。)但这对我来说似乎是一个非常困惑的情况,并且会阻止我想要的那种语义。 (即,使用 XUtilConnection 结构调用多个不同模块中的方法。)
最佳答案
我建议使用embedding .
In package xutil:
type XUtilConnection struct {
*ewmh.EWMH // Embed all methods of *ewmh.EWMH
*keybind.KeyBind // Embed all methods of *keybind.KeyBind
}
In package xutil/ewmh:
type EWMH struct {
Conn xgb.Conn
Root xgb.Id
// and any additional fields that are needed
}
// Some EWMH methods:
func (e *EWMH) GetAtom(name string) { ... }
func (e *EWMH) ...
In package xutil/keybind:
type KeyBind struct {
Conn xgb.Conn
Root xgb.Id
// and any additional fields that are needed
}
// Some keybind methods:
func (k *KeyBind) GetKeyCode(s string) { ... }
func (k *KeyBind) ...
这将使您能够直接对 *XUtilConnection
类型的值调用 EWMH
和 KeyBind
的方法:
var c *XUtilConnection = ...
c.GetAtom("_NET_ACTIVE_WINDOW") // Call (*emwh.EWMH).GetAtom(string)
c.GetKeyCode("a") // Call (*keybind.KeyBind).GetKeyCode(string)
关于go - 如何在 Go 中正确构建带有子包的包,其中单一类型将成为大多数方法的接收者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9418599/