基本パッケージ

基本的なGoパッケージは、プロジェクトのルートディレクトリにすべてのコードが含まれています。プロジェクトは単一のモジュールで構成されており、単一のパッケージを含んでいます。パッケージ名はモジュール名の最後のパスコンポーネントと一致します。単一のGoファイルを必要とする非常にシンプルなパッケージの場合、プロジェクト構造は次のようになります:

  1. project-root-directory/
  2. go.mod
  3. modname.go
  4. modname_test.go

[この文書全体で、ファイル/パッケージ名は完全に任意です]

このディレクトリがgithub.com/someuser/modnameにあるGitHubリポジトリにアップロードされると仮定すると、go.modファイルのmodule行にはmodule github.com/someuser/modnameと記載されている必要があります。

  1. ``````bash
  2. package modname
  3. // ... package code here
  4. `

ユーザーは次のようにimport-ingしてこのパッケージに依存できます:

  1. import "github.com/someuser/modname"

Goパッケージは、すべて同じディレクトリ内に存在する複数のファイルに分割できます。例えば:

  1. project-root-directory/
  2. go.mod
  3. modname.go
  4. modname_test.go
  5. auth.go
  6. auth_test.go
  7. hash.go
  8. hash_test.go

ディレクトリ内のすべてのファイルはpackage modnameを宣言します。

基本コマンド

基本的な実行可能プログラム(またはコマンドラインツール)は、その複雑さとコードサイズに応じて構成されます。最もシンプルなプログラムは、func mainが定義されている単一のGoファイルで構成できます。より大きなプログラムは、複数のファイルにコードを分割でき、すべてpackage mainを宣言します:

  1. project-root-directory/
  2. go.mod
  3. auth.go
  4. auth_test.go
  5. client.go
  6. main.go

ここで、main.goファイルにはfunc mainが含まれていますが、これは単なる慣例です。「main」ファイルは、modname.gomodnameの適切な値の場合)または他の何かと呼ぶこともできます。

このディレクトリがgithub.com/someuser/modnameにあるGitHubリポジトリにアップロードされると仮定すると、go.modファイルのmodule行には次のように記載されている必要があります:

  1. module github.com/someuser/modname

ユーザーは次のようにして自分のマシンにインストールできる必要があります:

  1. $ go install github.com/someuser/modname@latest

サポートパッケージを持つパッケージまたはコマンド

大きなパッケージやコマンドは、いくつかの機能をサポートパッケージに分割することで利益を得ることがあります。最初は、そのようなパッケージをinternalという名前のディレクトリに配置することをお勧めします; これにより 他のモジュールが、必ずしも公開したくないパッケージに依存するのを防ぎ、外部使用のためのサポートを行うことができます。他のプロジェクトは私たちのinternalディレクトリからコードをインポートできないため、APIをリファクタリングしたり、外部ユーザーを壊すことなく一般的に物事を移動したりする自由があります。したがって、パッケージのプロジェクト構造は次のようになります:

  1. project-root-directory/
  2. internal/
  3. auth/
  4. auth.go
  5. auth_test.go
  6. hash/
  7. hash.go
  8. hash_test.go
  9. go.mod
  10. modname.go
  11. modname_test.go

modname.goファイルはpackage modnameを宣言し、auth.gopackage authを宣言し、以下同様です。modname.goは次のようにauthパッケージをインポートできます:

  1. import "github.com/someuser/modname/internal/auth"

internalディレクトリ内のサポートパッケージを持つコマンドのレイアウトは非常に似ていますが、ルートディレクトリ内のファイルはpackage mainを宣言します。

複数のパッケージ

モジュールは複数のインポート可能なパッケージで構成できます。各パッケージは独自のディレクトリを持ち、階層的に構成できます。以下はサンプルプロジェクト構造です:

  1. project-root-directory/
  2. go.mod
  3. modname.go
  4. modname_test.go
  5. auth/
  6. auth.go
  7. auth_test.go
  8. token/
  9. token.go
  10. token_test.go
  11. hash/
  12. hash.go
  13. internal/
  14. trace/
  15. trace.go

リマインダーとして、go.modmodule行には次のように記載されていると仮定します:

  1. module github.com/someuser/modname

modnameパッケージはルートディレクトリに存在し、package modnameを宣言し、ユーザーは次のようにインポートできます:

  1. import "github.com/someuser/modname"

サブパッケージはユーザーによって次のようにインポートできます:

  1. import "github.com/someuser/modname/auth"
  2. import "github.com/someuser/modname/auth/token"
  3. import "github.com/someuser/modname/hash"
  1. <a name="multiple-commands"></a>
  2. ### 複数のコマンド
  3. 同じリポジトリ内の複数のプログラムは、通常、別々のディレクトリを持ちます:
  4. ``````bash
  5. project-root-directory/
  6. go.mod
  7. internal/
  8. ... shared internal packages
  9. prog1/
  10. main.go
  11. prog2/
  12. main.go
  13. `

各ディレクトリ内で、プログラムのGoファイルはpackage mainを宣言します。トップレベルのinternalディレクトリには、リポジトリ内のすべてのコマンドで使用される共有パッケージが含まれることがあります。

ユーザーは次のようにしてこれらのプログラムをインストールできます:

  1. $ go install github.com/someuser/modname/prog1@latest
  2. $ go install github.com/someuser/modname/prog2@latest

一般的な慣例は、リポジトリ内のすべてのコマンドをcmdディレクトリに配置することです。これは、コマンドのみで構成されるリポジトリでは厳密には必要ありませんが、コマンドとインポート可能なパッケージの両方を持つ混合リポジトリでは非常に便利です。

同じリポジトリ内のパッケージとコマンド

時には、リポジトリがインポート可能なパッケージと関連機能を持つインストール可能なコマンドの両方を提供します。このようなリポジトリのサンプルプロジェクト構造は次のとおりです:

  1. project-root-directory/
  2. go.mod
  3. modname.go
  4. modname_test.go
  5. auth/
  6. auth.go
  7. auth_test.go
  8. internal/
  9. ... internal packages
  10. cmd/
  11. prog1/
  12. main.go
  13. prog2/
  14. main.go

このモジュールがgithub.com/someuser/modnameと呼ばれると仮定すると、ユーザーは次のようにしてパッケージをインポートできます:

  1. import "github.com/someuser/modname"
  2. import "github.com/someuser/modname/auth"

そして、プログラムを次のようにインストールできます:

  1. $ go install github.com/someuser/modname/cmd/prog1@latest
  2. $ go install github.com/someuser/modname/cmd/prog2@latest

サーバープロジェクト

Goはサーバーを実装するための一般的な言語の選択です。サーバー開発の多くの側面があるため、このようなプロジェクトの構造には非常に大きなバリエーションがあります:プロトコル(REST?gRPC?)、デプロイメント、フロントエンドファイル、コンテナ化、スクリプトなど。ここでは、Goで書かれたプロジェクトの部分に焦点を当てます。

サーバープロジェクトには通常、エクスポート用のパッケージはありません。サーバーは通常、自己完結型のバイナリ(またはバイナリのグループ)だからです。したがって、サーバーのロジックを実装するGoパッケージはinternalディレクトリに保持することをお勧めします。さらに、プロジェクトには非Goファイルを持つ多くの他のディレクトリがある可能性があるため、すべてのGoコマンドをcmdディレクトリにまとめておくことが良いアイデアです:

  1. project-root-directory/
  2. go.mod
  3. internal/
  4. auth/
  5. ...
  6. metrics/
  7. ...
  8. model/
  9. ...
  10. cmd/
  11. api-server/
  12. main.go
  13. metrics-analyzer/
  14. main.go
  15. ...
  16. ... the project's other directories with non-Go code

サーバーリポジトリが他のプロジェクトと共有するのに役立つパッケージを成長させる場合、これらを別のモジュールに分割するのが最善です。