go - 如何在 Go 中正确构建带有子包的包,其中单一类型将成为大多数方法的接收者?

标签 go package

我目前正处于编写实用程序库的设计阶段,该库将与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 类型的值调用 EWMHKeyBind 的方法:

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/

相关文章:

go - 不能在映射值中使用 my_module.New(类型 func() (*my_module.MyModule, error))作为类型 func() (core.Module, error)

mysql - Golang 将参数传递给 gorilla 路由器

linux - 回答 golang 中的密码 shell 提示

go - 如何在 Go 中使用 Minio 预签名 URL

r - 使用 roxygen2 生成命名空间 : a small example or template

android - PackageManager.getInstalledPackages() 返回空列表

go - 如果在第一次迭代和第二次迭代之间有一个小时刻

python - 无法从同一包导入 python 模块

java - 如何获取maven库的jar文件?

python:列出包内的模块