Go言語

Google開発のシンプルで高速なコンパイル言語

Go言語とは

Goは2009年にGoogleが開発した静的型付けコンパイル言語です。 シンプルな構文、高速なコンパイル、組み込みの並行処理機能が特徴。 Kubernetes、Docker、Terraform等、インフラツールの標準言語となっています。

Goの実行アーキテクチャ

main.go
ソースコード
go build
コンパイラ
バイナリ
シングルファイル
実行
依存なし

ポイント: Goは静的リンクでシングルバイナリを生成。 実行環境にGoランタイムやライブラリのインストールが不要。 Dockerイメージも軽量化できる(scratch/distrolessベース)。

Goランタイムの構造

Goroutineスケジューラ

軽量スレッド(goroutine)をOSスレッドにマッピング。M:Nスケジューリング。

ガベージコレクタ

並行マーク&スイープ。低レイテンシ重視。STW時間を最小化。

ネットワークポーラー

epoll/kqueueを抽象化。非同期I/Oを同期的に記述。

Goroutineと並行処理

Goroutineは軽量な並行処理の単位。 OSスレッド(数MB)と比べ、goroutineは約2KBで起動可能。 数十万のgoroutineを同時に実行できる。

1// Goroutineの基本
2func main() {
3 // goキーワードで並行実行
4 go func() {
5 fmt.Println("Hello from goroutine")
6 }()
7
8 // Channelで通信
9 ch := make(chan string)
10 go func() {
11 ch <- "message" // 送信
12 }()
13 msg := <-ch // 受信
14 fmt.Println(msg)
15}
16
17// Worker Pool パターン
18func worker(id int, jobs <-chan int, results chan<- int) {
19 for j := range jobs {
20 results <- j * 2
21 }
22}
23
24func main() {
25 jobs := make(chan int, 100)
26 results := make(chan int, 100)
27
28 // 3つのworkerを起動
29 for w := 1; w <= 3; w++ {
30 go worker(w, jobs, results)
31 }
32
33 // ジョブを投入
34 for j := 1; j <= 5; j++ {
35 jobs <- j
36 }
37 close(jobs)
38
39 // 結果を収集
40 for a := 1; a <= 5; a++ {
41 <-results
42 }
43}

Goの主要な特徴

シンプルな構文

キーワードは25個のみ。継承なし、ジェネリクスは1.18から限定的にサポート。 「一つのことを一つの方法で」という設計思想。

高速なコンパイル

依存関係の解析が効率的で、大規模プロジェクトでも数秒でコンパイル完了。 開発サイクルが速い。

クロスコンパイル

GOOS/GOARCHを指定するだけで異なるOS/アーキテクチャ向けにビルド可能。

1# Linux向けにビルド(Mac上で)
2GOOS=linux GOARCH=amd64 go build -o myapp-linux
3
4# Windows向け
5GOOS=windows GOARCH=amd64 go build -o myapp.exe
6
7# ARM (Raspberry Pi等)
8GOOS=linux GOARCH=arm64 go build -o myapp-arm

標準ライブラリ

HTTP、JSON、暗号化、テスト等、実用的な機能が標準で充実。 外部依存を最小限に抑えられる。

エラーハンドリング

Goは例外(exception)を使わず、エラーを戻り値として返す設計。 明示的なエラーチェックが必要だが、エラーの流れが明確。

1// エラーは戻り値の最後
2func readFile(path string) ([]byte, error) {
3 data, err := os.ReadFile(path)
4 if err != nil {
5 return nil, fmt.Errorf("failed to read %s: %w", path, err)
6 }
7 return data, nil
8}
9
10// 呼び出し側で必ずチェック
11func main() {
12 data, err := readFile("config.json")
13 if err != nil {
14 log.Fatal(err)
15 }
16 // dataを使用
17}
18
19// Go 1.13以降: errors.Is, errors.As でエラー判定
20if errors.Is(err, os.ErrNotExist) {
21 // ファイルが存在しない
22}

SRE/インフラでの活用

CLIツール

kubectl, terraform, docker - シングルバイナリで配布が容易

Kubernetes関連

Operator開発、CRD、client-go - K8sエコシステムの標準

監視ツール

Prometheus, Grafana Agent - 高性能なメトリクス収集

API/マイクロサービス

低レイテンシ、高スループット、省メモリ

標準的なプロジェクト構成

1myproject/
2├── cmd/
3│ └── myapp/
4│ └── main.go # エントリーポイント
5├── internal/ # 内部パッケージ(外部からimport不可)
6│ ├── handler/
7│ └── service/
8├── pkg/ # 公開パッケージ
9│ └── client/
10├── api/ # API定義(OpenAPI, Protocol Buffers)
11├── configs/ # 設定ファイル
12├── scripts/ # ビルド・デプロイスクリプト
13├── go.mod # モジュール定義
14├── go.sum # 依存関係のチェックサム
15├── Makefile
16└── Dockerfile