
こんにちは。よっしーです(^^)
本日は、Go言語のよくある質問 について解説しています。
背景
Go言語を学んでいると「なんでこんな仕様になっているんだろう?」「他の言語と違うのはなぜ?」といった疑問が湧いてきませんか。Go言語の公式サイトにあるFAQページには、そんな疑問に対する開発チームからの丁寧な回答がたくさん載っているんです。ただ、英語で書かれているため読むのに少しハードルがあるのも事実で、今回はこのFAQを日本語に翻訳して、Go言語への理解を深めていけたらと思い、これを読んだ時の内容を備忘として残しました。
Packages and Testing
複数ファイルのパッケージを作成するにはどうすればよいですか?
パッケージのすべてのソースファイルを、それら専用のディレクトリに配置してください。ソースファイルは、異なるファイルからの項目を自由に参照できます。前方宣言やヘッダーファイルは必要ありません。
複数のファイルに分割されていることを除けば、パッケージは単一ファイルのパッケージと同じようにコンパイルおよびテストされます。
解説
この問題は何について説明しているの?
Go言語で複数のファイルに分けてパッケージを作る方法についての説明です。プログラムが大きくなると、1つのファイルに全部書くのは大変なので、複数のファイルに分けたくなります。
基本的な用語
- パッケージ: 関連する機能をまとめたコードの集まり
- ソースファイル: プログラムのコードが書かれた
.go
ファイル - 前方宣言: 他の言語(C/C++など)で必要な「これから使う関数や型を事前に宣言する」こと
- ヘッダーファイル: C/C++などで使う
.h
ファイル(Goには不要!)
複数ファイルパッケージの作り方
ステップ1: ディレクトリを作る
パッケージ専用のディレクトリ(フォルダ)を作ります。
myproject/
└── mypackage/ ← パッケージ専用のディレクトリ
├── file1.go
├── file2.go
└── file3.go
ステップ2: 各ファイルに同じパッケージ名を書く
すべてのファイルの先頭に、同じパッケージ名を書きます。
file1.go:
package mypackage
func Hello() string {
return "Hello, " + GetName()
}
file2.go:
package mypackage
func GetName() string {
return "World"
}
file3.go:
package mypackage
const Version = "1.0.0"
ステップ3: 自由に参照できる!
重要なポイント: 同じパッケージ内なら、どのファイルからでも自由に関数や変数を使えます。
file1.go
からfile2.go
のGetName()
を直接呼べる- 順番は関係ない
- 特別な宣言は不要
他の言語との違い
C/C++の場合(複雑)
// hello.h (ヘッダーファイル)
#ifndef HELLO_H
#define HELLO_H
void hello(); // 前方宣言が必要
#endif
// hello.c
#include "hello.h"
void hello() {
// 実装
}
// main.c
#include "hello.h" // includeが必要
int main() {
hello();
}
Goの場合(シンプル!)
// hello.go
package main
func Hello() {
// 実装
}
// main.go
package main
func main() {
Hello() // そのまま使える!
}
ヘッダーファイルも、includeも、前方宣言も不要です!
具体例: 実践的なパッケージ構成
calculator/
├── add.go
├── subtract.go
└── multiply.go
add.go:
package calculator
func Add(a, b int) int {
return a + b
}
subtract.go:
package calculator
func Subtract(a, b int) int {
return a - b
}
multiply.go:
package calculator
func Multiply(a, b int) int {
// 他のファイルの関数も使える
result := Add(0, a) // add.goの関数を使用
// ...何らかの処理
return a * b
}
使う側(別のパッケージから):
package main
import "myproject/calculator"
func main() {
sum := calculator.Add(5, 3)
diff := calculator.Subtract(10, 4)
product := calculator.Multiply(2, 6)
}
よくある質問
Q1: ファイルの読み込み順序は重要?
A: いいえ! Goは全ファイルを同時に見るので、順序は関係ありません。
Q2: main.goという名前にする必要がある?
A: いいえ! ファイル名は自由です。ただし:
package main
にはmain()
関数が必要- ファイル名とパッケージ名は一致しなくてOK
Q3: 1つのディレクトリに複数のパッケージを入れられる?
A: いいえ! 1つのディレクトリには1つのパッケージのみです。
✅ 正しい:
myproject/
├── package1/
│ ├── file1.go (package package1)
│ └── file2.go (package package1)
└── package2/
└── file3.go (package package2)
❌ 間違い:
myproject/
├── file1.go (package package1)
└── file2.go (package package2) ← 同じディレクトリに異なるパッケージ!
Q4: テストファイルも同じディレクトリ?
A: はい! テストファイル(*_test.go
)も同じディレクトリに置きます。
calculator/
├── add.go
├── add_test.go ← テストファイル
├── subtract.go
└── subtract_test.go
コンパイルとテスト
コンパイル
# パッケージをビルド
go build ./mypackage
# または、使う側のmainパッケージをビルド
go build .
テスト
# パッケージをテスト
go test ./mypackage
# または、すべてのパッケージをテスト
go test ./...
単一ファイルでも複数ファイルでも、コマンドは同じです!
まとめ
Goで複数ファイルパッケージを作るのはとてもシンプル:
- ✅ パッケージ専用のディレクトリを作る
- ✅ すべてのファイルに同じ
package
名を書く - ✅ ファイル間で自由に関数や変数を参照できる
- ✅ ヘッダーファイル、include、前方宣言は不要
- ✅ コンパイルもテストも単一ファイルと同じ
Goの哲学
Goは「シンプルで分かりやすい」ことを重視しています。複数ファイルに分けても:
- 複雑な設定は不要
- 自然に書けばOK
- ビルドシステムが自動的に処理
これがGoの魅力の1つです。C/C++のような複雑なビルド設定や、includeの順序問題などに悩む必要がありません!
おわりに
本日は、Go言語のよくある質問について解説しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント