Go基礎 #1 はじめてのプログラム
このシリーズは、Go(Go言語)を初めて学ぶ方、または他の言語を知っていてGoに移ってくる方のための、7編の入門講座です。
- #1 はじめてのプログラム ← 今回の記事
- #2 変数、型、定数
- #3 制御フロー — if/for/switch
- #4 関数、多値返却、error型
- #5 コレクション — array/slice/map
- #6 構造体とメソッド
- #7 パッケージとモジュール (go mod)
今回の記事では — なぜGoを使うのかから整理し、セットアップして最初のプログラムをコンパイル・実行するところまで進めます。
Goとは何ですか? #
Go(またはGolang) は、2009年にGoogleが発表したコンパイル言語です。設計目標が明確です。
- シンプルな文法 — キーワードは25個だけ、学習曲線が緩やか
- 高速なコンパイルと実行 — 静的コンパイル、単一バイナリの結果物
- ゴルーチン(goroutine) — 軽量な並行性モデル
- 標準ライブラリ — HTTPサーバー、JSON、暗号化などが最初から豊富
CLIツール、バックエンドサーバー、分散システムで特に強みを発揮します。Docker、Kubernetes、TerraformのようなインフラツールはすべてGoで書かれています。
誰に向いていますか? #
次のうち1つでも当てはまれば、Goがよく合います。
- CLIツールを作りたい — 単一バイナリでデプロイしやすい
- HTTPサーバー / API — 標準ライブラリだけで堅牢なサーバー
- 並行性が重要なシステム — ゴルーチンが最もシンプルな答え
- JavaScript/Pythonからもっと速い言語に移りたい — 学習曲線が緩やか
C/C++ほどの低レベル制御はできませんが、システムプログラミングとアプリケーションプログラミングの間の良い接点です。
他の言語との比較 #
おおよその位置づけ。
| Go | Python | JavaScript | Rust | |
|---|---|---|---|---|
| 型 | 静的、推論 | 動的 | 動的 (TSは静的) | 静的、強力 |
| 実行 | コンパイル | インタプリタ | JIT | コンパイル |
| 学習曲線 | 緩やか | 最も緩やか | 緩やか | 急峻 |
| メモリ管理 | GC | GC | GC | 所有権/borrow checker |
| 並行性 | ゴルーチン | asyncio/threading | イベントループ | async + スレッド |
Goはシンプルさと性能の間の実用的な位置を占めています。
Goをインストールする #
macOS #
brew install goLinux #
# Ubuntu/Debian
sudo apt install golang-go
# または公式サイトからtarballを取得
# https://go.dev/dl/Windows #
go.dev/dl からMSIインストーラをダウンロード。または winget install GoLang.Go。
インストール確認 #
go version
# go version go1.22.0 darwin/arm64 のように出力このシリーズはGo 1.22以上を前提とします。ServeMuxパターンマッチング、genericsなど最新機能を活用します。
最初のプログラム — Hello World #
作業フォルダを作って:
mkdir hello-go
cd hello-go
go mod init hellogo mod init が新しいモジュールを始めます。go.mod ファイルが生成されます。これは #7 パッケージとモジュール で詳しく扱います。
main.go ファイルを作って次のように書きます。
package main
import "fmt"
func main() {
fmt.Println("こんにちは, Go!")
}実行:
go run main.go
# こんにちは, Go!go run はコンパイルと実行を一度に行います。コンパイル済みバイナリを別途作りたければ:
go build
./hello
# こんにちは, Go!go build はモジュール名と同じ名前のバイナリ(hello)を作ります。Goの最大の長所の一つがこれです — 依存関係がすべて静的にまとめられた単一の実行ファイル。
コードを一行ずつ読み解く #
package main
import "fmt"
func main() {
fmt.Println("こんにちは, Go!")
}package main— このファイルはmainパッケージに属します。実行可能なプログラムは常にmainパッケージのmain関数から始まります。import "fmt"— 標準ライブラリのfmtパッケージを取り込みます。fmtは入出力フォーマット用です。func main()— プログラムのエントリーポイント。仮引数も戻り値もない関数。fmt.Println(...)— fmtパッケージのPrintln関数を呼び出します。外部に公開される名前は常に大文字で始まります(Goの規則)。
Goの最も目立つ文法 — セミコロン、波括弧 #
1) セミコロンなし #
fmt.Println("a")
fmt.Println("b")行末のセミコロンは書きません。コンパイラが自動で処理します。ただし注意 — 開き波括弧は必ず同じ行に来なければなりません。
// OK
func main() {
fmt.Println("hi")
}
// ✗ コンパイルエラー
func main()
{
fmt.Println("hi")
}2) インデントはタブ #
Goは標準ツール gofmt がコードを自動フォーマットします。インデントはタブ、整列は決まった規則。このシリーズもgofmtの結果そのままで書きます。
3) 自動フォーマット — go fmt
#
go fmt ./...保存時に自動でフォーマットされるようエディタに設定しておきましょう。VS CodeのGo拡張が自動で処理してくれます。
変数を一度さらっと — プレビュー #
次の記事で詳しく扱いますが、雰囲気だけ。
package main
import "fmt"
func main() {
name := "カーティス"
age := 30
fmt.Printf("名前: %s, 年齢: %d\n", name, age)
}:= が宣言と代入を一度に行う短縮構文です。型は右辺から推論されます(ここでは string、int)。
コンパイル段階で捕まる事故たち #
Goが初めての人にとって意外な箇所。
1) 使わない変数はコンパイルエラー #
func main() {
x := 10 // ✗ x declared but not used
fmt.Println("hi")
}他の言語では警告程度ですが、Goはコンパイル自体を止めます。コード整理を強制する設計です。
2) 使わないimportもエラー #
import (
"fmt"
"strings" // ✗ "strings" imported and not used
)
func main() {
fmt.Println("hi")
}同じ理由で。gofmt と goimports が自動で整理してくれるので、エディタ設定さえちゃんとしていればほぼ出会いません。
3) 変数シャドウイング(shadow) — コンパイルは通る #
x := 10
if true {
x := 20 // 新しいx — 外側のxを隠すが通る
fmt.Println(x) // 20
}
fmt.Println(x) // 10これはコンパイルエラーではありませんが、しばしばバグの原因になります。ツール(go vet)が一部のケースを捕まえてくれます。
標準ツール — go コマンド
#
よく使うサブコマンド。
go run main.go # 実行
go build # ビルド
go test ./... # テスト (全パッケージ)
go fmt ./... # フォーマット
go vet ./... # 静的解析 (疑わしいパターン検査)
go mod tidy # 依存関係整理
go mod init <名前> # 新規モジュール開始
go get <パッケージ> # 依存関係追加./... は「現在のディレクトリとすべての配下」を意味します。
エディタ — VS Code + Go拡張 #
VS Code に Go拡張 を入れれば、補完、ジャンプ、フォーマット、リントがすべて動きます。最初に開くと追加ツールのインストール案内が出るので、すべてインストールしておきましょう。
JetBrainsのGoLandも人気ですが、VS Codeだけでほぼ十分です。
Go Playground — セットアップなしで試す #
go.dev/play はブラウザですぐにGoを実行できる公式ツールです。小さなサンプルを試すとき、またはコードを共有するときに便利です。
まとめ #
今回の記事で整理した内容:
- Goはシンプルな文法 + 静的コンパイル + 並行性に強い言語
- CLI、HTTPサーバー、分散システムに特に向く
- インストール確認は
go version。シリーズは1.22+前提 - 新規プロジェクトは
go mod initで開始 go run main.goまたはgo buildpackage main+func main()がエントリーポイント- 外部公開する名前は大文字で始める — Goの可視性規則
- 使わない変数/importはコンパイルエラー
gofmt/go vetなど標準ツールが豊富
次の記事(#2 変数、型、定数)ではGoの基本型、変数宣言の方法、定数とiotaパターンまで整理します。