go - ほとんどのメソッドで単一の型がレシーバーになるGoでサブパッケージを含むパッケージを適切に構成するにはどうすればよいですか?

go package-structuring

私はGoを拾い始めたばかりなので、明らかなものを逃した場合は、簡単に行く:-)

とにかく、私は現在、x-go-bindingとのやり取りを少し簡単にするユーティリティライブラリを作成する設計段階にあります。 (これは以前にPythonとxpybで行いました。)たとえば、EWMH specで定義された情報のクエリやキーのコールバック関数へのバインドに役立ちます。 (そして、はるかに。)したがって、パッケージレイアウトの最初のアイデアとして、以下を検討してください。


xutil

うん
キーバインド



それぞれが独自のパッケージです。 (標準ライブラリのイメージパッケージの設定方法に似ています。)

私の状況のユニークな点は、ほとんどすべての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タイプをどのサブパッケージのレシーバーとしても使用できなくなります。

私の答えは、この1つの大きなパッケージを異なる論理ファイルに分割することになると思いますが、これが名前空間の混乱につながるのではないかと心配しています。 (たとえば、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) ...


これにより、タイプEWMHの値に対してKeyBindおよび*XUtilConnectionのメソッドを直接呼び出すことができます。

var c *XUtilConnection = ...
c.GetAtom("_NET_ACTIVE_WINDOW")  // Call (*emwh.EWMH).GetAtom(string)
c.GetKeyCode("a")                // Call (*keybind.KeyBind).GetKeyCode(string)
関連記事

google-app-engine - GAE Go Json-RPC呼び出しの例

arm - Goツールは間違ったアーキテクチャ用にビルドされていますか?

go - 複数入力(fmt.Scanln)

udp - 分散サーバーのインスタンス間のデータブロードキャスト

networking - Goネットワークプログラミングライブラリ[終了]

xml - Goで非整列化を使用して名前空間のあるXML属性にアクセスする際の問題

go - GoとEchoを使い始められないようです

go - 配信不能トピックに転送して、Google Pub / Subの配信試行を制限するにはどうすればよいですか?

go - ハイパーレジャーファブリックのチェーンコードインスタンスからGoogle Cloud Storageにデータをアップロードできません

go - 歩哨メッセージをコンソールに出力する方法はありますか