Go言語入門:よくある質問 -Packages and Testing Vol.1-

スポンサーリンク
Go言語入門:よくある質問 -Packages and Testing Vol.1- ノウハウ
Go言語入門:よくある質問 -Packages and Testing Vol.1-
この記事は約7分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、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.goGetName()を直接呼べる
  • 順番は関係ない
  • 特別な宣言は不要

他の言語との違い

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で複数ファイルパッケージを作るのはとてもシンプル:

  1. ✅ パッケージ専用のディレクトリを作る
  2. ✅ すべてのファイルに同じpackage名を書く
  3. ✅ ファイル間で自由に関数や変数を参照できる
  4. ✅ ヘッダーファイル、include、前方宣言は不要
  5. ✅ コンパイルもテストも単一ファイルと同じ

Goの哲学

Goは「シンプルで分かりやすい」ことを重視しています。複数ファイルに分けても:

  • 複雑な設定は不要
  • 自然に書けばOK
  • ビルドシステムが自動的に処理

これがGoの魅力の1つです。C/C++のような複雑なビルド設定や、includeの順序問題などに悩む必要がありません!

おわりに 

本日は、Go言語のよくある質問について解説しました。

よっしー
よっしー

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

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました