Go ドキュメント
簡潔で実例中心の Go リファレンス。概念を読み、コードを見て、Coddy のジャーニーで実践しましょう。
Go のガイド付き学習を始めるはじめに
- Go言語とはGo(Golangとも呼ばれます)は、高速で信頼性の高いサーバーやツールを作るためにGoogleで設計された、静的型付けのコンパイル言語です。何ができるのか、何に使われているのか、どこが苦手なのかを解説します。
- GoのインストールWindows、macOS、LinuxでGoをダウンロードしてインストールする方法、go versionでの確認、GOPATHの意味、「go: command not found」エラーの直し方を解説します。
- Hello WorldGoのHello Worldプログラムを1行ずつ解説します。package main、importブロック、func main、fmt.Println、そして実行方法と初心者が最初に出会うコンパイルエラーまで。
- go runとgo buildgo run、go build、go installがそれぞれ何をするのか、Goがバイナリにどう名前を付けるのか、GOOSとGOARCHでのクロスコンパイル、そしてコミット前に実行したいgo fmtとgo vetのチェックを解説します。
- GoモジュールGoモジュールの仕組みを解説します。go mod initでの作成、モジュールパスの決め方、go getでの依存関係の追加、go mod tidyでの整理、go.sumの役割、ローカル開発で使うreplaceまで。
- パッケージとimportGoのパッケージの仕組みを解説します。package句、標準ライブラリとモジュールのパッケージのインポート、公開名と非公開名、パッケージの複数ファイルへの分割、internalパッケージ、インポートの別名、ブランクインポート、そしてgo run main.goで出る「undefined」エラーまで。
基本
- 変数Goでvarと短い形式の:=を使って変数を宣言する方法、ゼロ値とは何か、多重代入、そしてGoを始めたばかりの人がはまるシャドーイングと未使用変数のエラーを解説します。
- 定数Goのconstの仕組みを解説します。定数の宣言、型付き定数と型なし定数の違い、任意精度で計算される定数式、そしてGoに定数のスライス、マップ、構造体がない理由まで。
- 列挙型とiotaGoにenumキーワードはありません。このページでは、名前付きの型とiotaを使ったconstブロックというGoらしい代替手段と、String()、検証、パース、ビットフラグ、JSON対応の追加方法を紹介します。
- データ型Goの組み込み型を解説します。整数のサイズと範囲、float32とfloat64、bool、string、byteとrune、複素数、ゼロ値、そして%Tで値の型を表示する方法まで。
- 型変換Goで型を変換する方法を解説します。strconvによるintから文字列、文字列からintへの変換、浮動小数点数から整数への変換、T(v)による数値の変換、byteとrune、string(65)の罠、そして変換エラーの扱いまで。
- 文字列Goで文字列を扱う方法を解説します。stringsパッケージ(Split、Join、Contains、Replace、Fields、TrimSpace、ToUpper)、strings.Builderによる効率的な文字列の組み立て、複数行の生文字列、不変性、そしてlenがバイト数を数える理由まで。
- ルーンとバイトGoのruneとbyteの意味、文字列がUTF-8をどう保持するか、lenがバイト数を数える理由、rangeがルーンをデコードする仕組み、string・[]byte・[]runeの相互変換、そしてbytesパッケージの使い方を解説します。
- fmt.PrintfとSprintfGoのfmtパッケージが値を表示・整形する仕組みを解説します。Println、Printf、Sprintf、Errorfの違い、書式指定子の一覧(%v、%+v、%d、%s、%q、%f、%T、%wなど)、幅、精度、パディングまで。
制御構文
- if / elseGoのif、else if、elseの仕組みを解説します。条件を囲むかっこは不要で、波かっこは必須です。初期化文付きのif文とそのスコープ、if err != nilのイディオム、深いネストの代わりの早期リターンまで。
- forループGoのループのキーワードはforだけで、これですべてをまかないます。3つの節からなるカウンタのループ、条件だけのwhileループ、無限ループ、そしてスライス、マップ、文字列、チャネル、整数、関数に対するrange。ラベル付きのbreakとcontinue、Go 1.22でのループ変数の変更も扱います。
- whileループGoにwhileキーワードはありません。条件だけを書いたforループがGoのwhileループで、条件のないforは無限ループ、do-whileは最後にチェックを置いた無限ループです。
- rangeループfor rangeがスライス、配列、文字列、マップ、チャネル、整数、イテレータ関数に対して何を返すのか、値の変数がコピーである理由、rangeしながらスライスやマップを変更すると何が起きるのか、そしてGo 1.23の関数に対するrangeを解説します。
- switch文Goのswitchの仕組みを解説します。caseはデフォルトでフォールスルーせず、1つのcaseに複数の値を並べられ、条件のないswitchはif/elseの連鎖の代わりになります。初期化文付きのswitch、fallthroughキーワード、型スイッチの概要も扱います。
- 三項演算子Goに三項演算子(cond ? a : b)はありません。このページではその理由と、Goらしいif/elseでの書き換え、デフォルト値のためのcmp.Or、そしてジェネリックなヘルパー関数と、それが本物の三項演算子と違う点になる罠を紹介します。
関数
- 関数Goで関数を宣言して呼び出す方法を解説します。引数、型をまとめた引数、戻り値、値渡し、そして保存したり受け渡したりできる値としての関数まで。
- 複数の戻り値Goの関数は複数の値を返せます。このページでは構文、(value, error)の慣習、カンマokイディオム、名前付き戻り値、裸のreturn、ブランク識別子を扱います。
- 可変長引数関数Goの可変長引数関数は、1つの型の末尾の引数をいくつでも受け取ります。...Tの構文、s...でスライスを渡す方法、同じ配列を共有してしまう落とし穴、そしてfmt.Printlnが...anyを使う仕組みを解説します。
- クロージャGoの無名関数は、周りのスコープの変数を捕捉できます。それがクロージャになり、カウンタ、ジェネレータ、ミドルウェア、独自の状態を持つコールバックに使われます。
- defer文deferは、囲んでいる関数が戻るときに実行される呼び出しを予約します。LIFOの順序、引数が評価されるタイミング、ファイルのクローズとミューテックスのアンロック、ループ内のdefer、名前付き戻り値の変更を解説します。
- メソッドメソッドはレシーバーを持つ関数です。メソッドの宣言方法、値レシーバーとポインタレシーバーの使い分け、メソッドセットとインターフェース、構造体以外の型へのメソッドを解説します。
コレクション
- 配列Goの配列は型の一部である固定長を持ち、代入時にコピーされます。配列の宣言、走査、比較、受け渡しの方法と、ほとんどのGoのコードが代わりにスライスを使う理由を解説します。
- スライススライスはGoで日常的に使うリスト型です。make、appendと容量の拡張、lenとcapの違い、スライス操作が元の配列を共有する仕組み(とそれが生むバグ)、copy、slicesパッケージ、2次元スライス、nilと空の違いを解説します。
- マップGoのマップはキーと値のペアを保存し、高速に検索できます。作り方、カンマokでキーの存在を確認する方法、削除、(ランダムな順序での)走査、キーのソート、構造体の格納、そしてnilマップと並行書き込みによるpanicの避け方を解説します。
- 集合(Set)Goに組み込みの集合型はありません。標準的なイディオムは、値を空の構造体にしたマップです。追加、存在確認、削除、和集合、積集合、差集合、そして小さなジェネリックなSetの書き方を解説します。
- ソートGoでslices.Sortとslices.SortFuncを使ってスライスをソートする方法、cmp.Compareで構造体を1つまたは複数のフィールドでソートする方法、安定ソートで等しい要素の順序を保つ方法、そして古いsort.Sliceのコードの読み方を解説します。
構造体・インターフェース・ジェネリクス
- 構造体構造体は名前付きのフィールドを1つの型にまとめます。定義と初期化の方法、ゼロ値、構造体へのポインタ、無名構造体、比較、構造体タグ、そしてNewXというコンストラクタの慣習を解説します。
- ポインタポインタは値のアドレスを保持します。&と*、new、構造体へのポインタ、ローカル変数へのポインタを安全に返せる理由、ポインタを使うべき場面、そしてnilポインタの参照外しによるpanicを解説します。
- インターフェースGoのインターフェースは暗黙に満たされます。必要なメソッドを持つ型はどれでもそれを実装します。io.Readerやfmt.Stringerのような小さなインターフェース、空のインターフェースany、nilインターフェースの落とし穴、そして「インターフェースを受け取り、構造体を返す」を解説します。
- 構造体の埋め込み埋め込みは、ある型をフィールド名なしで別の型の中に置くもので、そのフィールドとメソッドが外側の型に昇格されます。昇格の仕組み、インターフェースの埋め込み、名前の衝突、そして埋め込みが継承ではない理由を解説します。
- 型アサーション型アサーションは、インターフェースから具体的な値を取り出します。x.(T)、決してpanicしないカンマok形式、別のインターフェースへのアサーション、型スイッチ、そしてラップされたエラーのためのerrors.Asを解説します。
- ジェネリクスジェネリクス(Go 1.18以降)を使うと、1つの関数や型が型安全なまま多くの型で動きます。型パラメータ、any・comparable・cmp.Orderedの制約、~を使った独自の制約、ジェネリックな型、そして使うべきでない場面を解説します。
エラー
- エラー処理Goはエラーを関数から返される普通の値として扱います。errorインターフェース、if err != nil、errors.Newとfmt.Errorf、文脈を付けてエラーを返す方法、errors.Isとerrors.Asでのチェック、そして各エラーを一度だけ処理することを解説します。
- カスタムエラー番兵エラーと独自のエラー型を定義し、%wでエラーをラップし、errors.Isとerrors.Asでチェックし、errors.Joinで複数をまとめ、必要なときにUnwrapとIsのメソッドを書く方法を解説します。
- panicとrecoverpanicは通常の実行を止め、deferした呼び出しを実行しながらスタックを巻き戻します。panicの原因、deferした関数の中のrecoverでpanicを止める方法、目にすることになる実行時エラーのメッセージ、そしてpanicするのが正しい場面を解説します。
並行処理
- ゴルーチンgoキーワードで関数を並行に実行する方法、終了を待つ方法、結果を受け取る方法、そしてゴルーチンが招きやすいデータ競合、リーク、クラッシュを避ける方法を解説します。
- チャネルGoのチャネルがゴルーチン間で値を受け渡す仕組みを解説します。バッファなしとバッファ付きのチャネル、クローズとrange、方向付きの型、デッドロックのエラー、そしてチャネルで作るパイプラインまで。
- select文selectが複数のチャネル操作を同時に待つ仕組みを解説します。準備のできたケースからの選択、defaultによるブロックしない送受信、time.Afterによるタイムアウト、そしてquitチャネルやcontextによるループの停止まで。
- WaitGroupsync.WaitGroupがゴルーチンの集まりの終了を待つ仕組みを解説します。Add、Done、Waitのルール、ポインタで渡さなければならない理由、結果とエラーの集め方、そしてそれを使って作るワーカープールまで。
- ミューテックスsync.Mutexとsync.RWMutexでゴルーチン間の共有状態を保護する方法、sync/atomicで十分な場面、sync.Onceで初期化を一度だけ実行する方法、そしてデッドロックを招くロックの間違いを解説します。
- contextパッケージcontext.ContextがGoのプログラム全体にキャンセル、期限、リクエストスコープの値をどう運ぶかを解説します。Background、WithCancel、WithTimeout、WithValue、selectでのctx.Done、そしてHTTPのサーバーとクライアントでのcontextまで。
標準ライブラリ
- timeパッケージGoで日付と時刻を扱う方法を解説します。time.Nowとtime.Sleep、Durationの計算、FormatとParseで使う2006-01-02 15:04:05という基準レイアウト、タイムゾーン、Unixタイムスタンプ、そしてタイマーとティッカーまで。
- JSONencoding/jsonでGoのJSONをエンコード・デコードする方法を解説します。MarshalとUnmarshal、omitemptyやomitzeroなどの構造体タグ、整形出力、map[string]anyへのデコード、未知のフィールドの拒否、そしてDecoderによるストリーム処理まで。
- ファイルの読み書きGoでファイルを読み書きする方法を解説します。os.ReadFileとos.WriteFile、bufio.Scannerでの1行ずつの読み込み、os.OpenFileでの追記、ファイルが存在するかの確認、そしてディレクトリの操作まで。
- HTTPサーバーGoの標準のnet/httpパッケージでWebサーバーを作る方法を解説します。ハンドラ、メソッドとパスのワイルドカードを使うServeMuxのルーティング(Go 1.22)、JSONレスポンス、ステータスコード、ミドルウェア、タイムアウト、グレースフルシャットダウンまで。
- HTTPクライアントnet/httpでGoからHTTPリクエストを送る方法を解説します。http.Get、ボディの読み込みとクローズ、ステータスコードのチェック、http.Clientのタイムアウト、コンテキストとヘッダー付きのリクエスト、クエリパラメータ、JSONのPOSTまで。
- コマンドライン引数Goのプログラムがコマンドラインを読む方法を解説します。os.Args、型付きのオプションのためのflagパッケージ、FlagSetによるサブコマンド、os.Getenvとos.LookupEnvによる環境変数、そしてos.Exitによる終了コードまで。
- 正規表現regexpパッケージでGoの正規表現を使う方法を解説します。MustCompile、MatchString、FindStringとFindAllString、キャプチャグループと名前付きグループ、ReplaceAllString、そして後読みがないなどのRE2構文の制限まで。
- ログ出力Goでログを出す方法を解説します。フラグとlog.Fatalを持つ昔ながらのlogパッケージと、レベル、キーと値の属性、テキストとJSONのハンドラ、Withで文脈を運ぶロガーを備えた構造化ログのlog/slog(Go 1.21)まで。