基本パッケージ
基本的なGoパッケージは、プロジェクトのルートディレクトリにすべてのコードが含まれています。プロジェクトは単一のモジュールで構成されており、単一のパッケージを含んでいます。パッケージ名はモジュール名の最後のパスコンポーネントと一致します。単一のGoファイルを必要とする非常にシンプルなパッケージの場合、プロジェクト構造は次のようになります:
project-root-directory/
go.mod
modname.go
modname_test.go
[この文書全体で、ファイル/パッケージ名は完全に任意です]
このディレクトリがgithub.com/someuser/modname
にあるGitHubリポジトリにアップロードされると仮定すると、go.mod
ファイルのmodule
行にはmodule github.com/someuser/modname
と記載されている必要があります。
``````bash
package modname
// ... package code here
`
ユーザーは次のようにimport
-ingしてこのパッケージに依存できます:
import "github.com/someuser/modname"
Goパッケージは、すべて同じディレクトリ内に存在する複数のファイルに分割できます。例えば:
project-root-directory/
go.mod
modname.go
modname_test.go
auth.go
auth_test.go
hash.go
hash_test.go
ディレクトリ内のすべてのファイルはpackage modname
を宣言します。
基本コマンド
基本的な実行可能プログラム(またはコマンドラインツール)は、その複雑さとコードサイズに応じて構成されます。最もシンプルなプログラムは、func main
が定義されている単一のGoファイルで構成できます。より大きなプログラムは、複数のファイルにコードを分割でき、すべてpackage main
を宣言します:
project-root-directory/
go.mod
auth.go
auth_test.go
client.go
main.go
ここで、main.go
ファイルにはfunc main
が含まれていますが、これは単なる慣例です。「main」ファイルは、modname.go
(modname
の適切な値の場合)または他の何かと呼ぶこともできます。
このディレクトリがgithub.com/someuser/modname
にあるGitHubリポジトリにアップロードされると仮定すると、go.mod
ファイルのmodule
行には次のように記載されている必要があります:
module github.com/someuser/modname
ユーザーは次のようにして自分のマシンにインストールできる必要があります:
$ go install github.com/someuser/modname@latest
サポートパッケージを持つパッケージまたはコマンド
大きなパッケージやコマンドは、いくつかの機能をサポートパッケージに分割することで利益を得ることがあります。最初は、そのようなパッケージをinternal
という名前のディレクトリに配置することをお勧めします; これにより 他のモジュールが、必ずしも公開したくないパッケージに依存するのを防ぎ、外部使用のためのサポートを行うことができます。他のプロジェクトは私たちのinternal
ディレクトリからコードをインポートできないため、APIをリファクタリングしたり、外部ユーザーを壊すことなく一般的に物事を移動したりする自由があります。したがって、パッケージのプロジェクト構造は次のようになります:
project-root-directory/
internal/
auth/
auth.go
auth_test.go
hash/
hash.go
hash_test.go
go.mod
modname.go
modname_test.go
modname.go
ファイルはpackage modname
を宣言し、auth.go
はpackage auth
を宣言し、以下同様です。modname.go
は次のようにauth
パッケージをインポートできます:
import "github.com/someuser/modname/internal/auth"
internal
ディレクトリ内のサポートパッケージを持つコマンドのレイアウトは非常に似ていますが、ルートディレクトリ内のファイルはpackage main
を宣言します。
複数のパッケージ
モジュールは複数のインポート可能なパッケージで構成できます。各パッケージは独自のディレクトリを持ち、階層的に構成できます。以下はサンプルプロジェクト構造です:
project-root-directory/
go.mod
modname.go
modname_test.go
auth/
auth.go
auth_test.go
token/
token.go
token_test.go
hash/
hash.go
internal/
trace/
trace.go
リマインダーとして、go.mod
のmodule
行には次のように記載されていると仮定します:
module github.com/someuser/modname
modname
パッケージはルートディレクトリに存在し、package modname
を宣言し、ユーザーは次のようにインポートできます:
import "github.com/someuser/modname"
サブパッケージはユーザーによって次のようにインポートできます:
import "github.com/someuser/modname/auth"
import "github.com/someuser/modname/auth/token"
import "github.com/someuser/modname/hash"
<a name="multiple-commands"></a>
### 複数のコマンド
同じリポジトリ内の複数のプログラムは、通常、別々のディレクトリを持ちます:
``````bash
project-root-directory/
go.mod
internal/
... shared internal packages
prog1/
main.go
prog2/
main.go
`
各ディレクトリ内で、プログラムのGoファイルはpackage main
を宣言します。トップレベルのinternal
ディレクトリには、リポジトリ内のすべてのコマンドで使用される共有パッケージが含まれることがあります。
ユーザーは次のようにしてこれらのプログラムをインストールできます:
$ go install github.com/someuser/modname/prog1@latest
$ go install github.com/someuser/modname/prog2@latest
一般的な慣例は、リポジトリ内のすべてのコマンドをcmd
ディレクトリに配置することです。これは、コマンドのみで構成されるリポジトリでは厳密には必要ありませんが、コマンドとインポート可能なパッケージの両方を持つ混合リポジトリでは非常に便利です。
同じリポジトリ内のパッケージとコマンド
時には、リポジトリがインポート可能なパッケージと関連機能を持つインストール可能なコマンドの両方を提供します。このようなリポジトリのサンプルプロジェクト構造は次のとおりです:
project-root-directory/
go.mod
modname.go
modname_test.go
auth/
auth.go
auth_test.go
internal/
... internal packages
cmd/
prog1/
main.go
prog2/
main.go
このモジュールがgithub.com/someuser/modname
と呼ばれると仮定すると、ユーザーは次のようにしてパッケージをインポートできます:
import "github.com/someuser/modname"
import "github.com/someuser/modname/auth"
そして、プログラムを次のようにインストールできます:
$ go install github.com/someuser/modname/cmd/prog1@latest
$ go install github.com/someuser/modname/cmd/prog2@latest
サーバープロジェクト
Goはサーバーを実装するための一般的な言語の選択です。サーバー開発の多くの側面があるため、このようなプロジェクトの構造には非常に大きなバリエーションがあります:プロトコル(REST?gRPC?)、デプロイメント、フロントエンドファイル、コンテナ化、スクリプトなど。ここでは、Goで書かれたプロジェクトの部分に焦点を当てます。
サーバープロジェクトには通常、エクスポート用のパッケージはありません。サーバーは通常、自己完結型のバイナリ(またはバイナリのグループ)だからです。したがって、サーバーのロジックを実装するGoパッケージはinternal
ディレクトリに保持することをお勧めします。さらに、プロジェクトには非Goファイルを持つ多くの他のディレクトリがある可能性があるため、すべてのGoコマンドをcmd
ディレクトリにまとめておくことが良いアイデアです:
project-root-directory/
go.mod
internal/
auth/
...
metrics/
...
model/
...
cmd/
api-server/
main.go
metrics-analyzer/
main.go
...
... the project's other directories with non-Go code
サーバーリポジトリが他のプロジェクトと共有するのに役立つパッケージを成長させる場合、これらを別のモジュールに分割するのが最善です。