Go
Goは、Googleが開発したオープンソースの汎用プログラミング言語であり、システムプログラミングを主な目的として設計されています[1]。 静的型付け言語であるため、高速で効率的なプログラムを作成することができ、また、並行処理を簡単に実装できるため、高い並行性を持ちます。 Goの文法はシンプルで読みやすく、効率的にコーディングできるため、開発者は迅速に新しいコードを書くことができます。 Goは自動的にメモリを管理するため、メモリ管理に関する手間を減らすことができます。 さらに、Windows、macOS、Linuxなど、多くのプラットフォームで動作し、標準ライブラリが豊富であり、多くの外部ライブラリが存在するため、広範な用途に対応することができます。 Goのコミュニティは活発であり、多くの開発者が参加しているため、質問や問題解決のためのリソースが豊富であり、新しい機能やライブラリが定期的にリリースされています。
この教科書では、初めてGoを学ぶ人から、より高度なトピックに興味のある人まで、幅広い読者を対象に、Goの基本から応用までを網羅的に解説します。
目次
[編集]- チュートリアル篇
- 環境構築
- 実行の方法 — Hello, World
- 文法の概要
- 変数と型変換
- 算術演算と数学関数
- 条件分岐と繰り返し — if, switch, select, for, break, continue, return
- 関数
- メソッドとインターフェース
- ジェネリクス
- 再帰的関数呼出し
- メソッドチェイン
- defer, panicとrecover
- 並行処理
- 配列型とスライス型
- マップ型
- 構造体型と構造体スライス
- イテレータ
- Goのプログラムがどんなアセンブリにコンパイルされるか? — go tool objdump
- クロスコンパイル — GOOS, GOARCH
- cgoでGoのコードからCの関数を利用する — cgo
- Goのコードでgoのバージョンを調べる方法
- HTTP
- ファイル入出力
- コードギャラリー
- リファレンス篇
- ソースコードの表現方法
- キーワードと宣言済み識別子 — キーワード・宣言済み識別子(組込み型・組込み関数)
- 字句的要素
- 定数と変数 — 定数(iota)・変数
- 型
- 型と値の特性
- ブロック・宣言とスコープ — ブロック・宣言とスコープ
- 式 — 演算子
- 文
- パッケージ
- プログラムの初期化と実行
- エラー
- EBNF
- 標準ライブラリー篇
- 改廃された技術
バージョン間の変更点
[編集]Go は、約半年ごとに新しいバージョンがリリースされます。バージョンが変わると、言語仕様に追加変更があったり、ツールチェーン、ランタイム、およびライブラリの実装に変更が加えられることがあり、稀に既存のプログラムに影響が出ることもあります。以下に、最新のバージョンから順に変更点を記載します。
Go 1.23
[編集]Go 1.23が、2024年8月にリリースされました[2][3]。 Go 1.23のリリースでは、いくつかの重要な新機能と改善が含まれています。最も注目すべき変更点は以下です。
- 言語の変更点:
-
- "for-range" ループでイテレータ関数がサポートされるようになりました。これにより、カスタムイテレーション値を生成する関数を使用できます。
- ジェネリック型エイリアスのプレビューサポートが追加されました(GOEXPERIMENT=aliastypeparamsを有効にする必要があります)。
- 新しい標準パッケージ:
-
- uniqueパッケージ:値の正規化(インターン化やハッシュコンス化)を行うための機能を提供します。
- iterパッケージ:ユーザー定義のイテレータ機能を提供します。
- structsパッケージ:構造体のメモリレイアウトなどのプロパティを制御する機能を提供します。
- パフォーマンスの改善点:
-
- Profile Guided Optimization (PGO)のビルドオーバーヘッドが大幅に削減されました。以前は100%以上の増加が見られましたが、今回のリリースでは一桁台のパーセンテージまで改善されています。
- コンパイラがローカル変数のスタックフレームスロットを最適化し、関数内の異なる領域で重複して使用できるようになり、スタック使用量が削減されました。
- テレメトリーと開発者ツール:
-
- Goツールチェーンが使用状況と問題点の統計情報を収集できるテレメトリー機能が追加されました(オプトイン方式)。
- go vetコマンドにstdversionアナライザーが追加され、使用しているGoバージョンと互換性のないシンボルの参照を検出できるようになりました。
- プラットフォームサポートの変更:
-
- macOSは11 (Big Sur)以降が必要になりました。
- Linux kernelは2.6.32以降が必要です(Go 1.24では3.2以降になる予定)。
- OpenBSDの64-bit RISC-Vサポートが試験的に追加されました。
また、time.TimerとTime.Tickerの実装が大幅に改善され、未使用のタイマーがガベージコレクションの対象となるようになりました。セキュリティ面では、TLSクライアントがEncrypted Client Helloをサポートし、3DESの暗号スイートがデフォルトリストから削除されるなどの改善が行われています。
Go 1.22
[編集]Go 1.22が、2024年2月にリリースされました[4][5]。 Go 1.22のリリースでは、いくつかの重要な新機能と改善が含まれています。最も注目すべき変更点は以下です。
- 言語の変更点:
-
- 長らく問題視されてきた「for」ループの変数スコープが変更されました。以前は変数が一度だけ作成され、各イテレーションで更新されていましたが、Go 1.22以降は各イテレーションで新しい変数が作成されるようになり、意図しない共有の問題が解消されました。
- 整数の範囲に対する
range
のサポートが追加されました。例えば、for i := range 10
のような構文が可能になりました。
- パフォーマンスの改善点:
-
- ガベージコレクションのメタデータを各ヒープオブジェクトの近くに配置するように最適化されました。これにより、CPUパフォーマンスが1-3%向上し、ほとんどのGoプログラムのメモリオーバーヘッドが約1%削減されました。
- コンパイラのプロファイル誘導最適化(PGO)が改善され、より多くのインターフェースメソッド呼び出しの仮想化解除が可能になりました。代表的なGoプログラムの多くで、PGOを有効にすることで2-14%のパフォーマンス向上が見られます。
- コンパイラは仮想化解除とインライン化を交互に行うようになり、インターフェースメソッド呼び出しの最適化が向上しました。
- 標準ライブラリの追加と改善:
-
- 標準ライブラリで初めてのv2パッケージとなる
math/rand/v2
が追加されました。新しいパッケージでは、ChaCha8とPCGという2つの現代的な疑似乱数生成器を提供し、より高速なアルゴリズムを採用しています。 net/http.ServeMux
のHTTPルーティングがより表現力豊かになりました。メソッドとワイルドカードをサポートし、例えば"POST /items/create"や"/items/{id}"のようなパターンが使用可能になりました。database/sql
パッケージにNull[T]
型が追加され、任意の型のnullableカラムをスキャンする機能が提供されます。go/version
パッケージが追加され、Goバージョン文字列の検証と比較機能が提供されます。slices
パッケージに複数のスライスを連結するConcat
関数が追加されました。
- 標準ライブラリで初めてのv2パッケージとなる
- ツールの改善:
-
- Goコマンドでワークスペースのvendorディレクトリがサポートされるようになりました。
go work vendor
でディレクトリを作成し、-mod=vendor
フラグで使用できます。 - トレースツールのWebUIが改良され、スレッド指向のビューでトレースを探索できるようになりました。また、すべてのシステムコールの完全な実行時間が表示されるようになりました。
go vet
ツールに新しい警告が追加され、appendに値を渡し忘れた場合や、time.Since呼び出しの遅延に関する問題を検出できるようになりました。
- Goコマンドでワークスペースのvendorディレクトリがサポートされるようになりました。
また、macOSのx86-64アーキテクチャ(darwin/amd64)向けのGoツールチェーンが、デフォルトで位置独立実行形式(PIE)を生成するようになりました。Go 1.23以降はmacOS 11 Big Sur以降が必要になることも発表されています。
Go 1.21
[編集]Go 1.21が、2023年8月にリリースされました[6][7]。
Go 1.21では、リリースの番号付けにわずかな変更が導入されました。Go 1.Nは、過去にGo言語のバージョン全体とリリースファミリー、およびそのファミリー内の最初のリリースを指すために使用されていました。しかし、Go 1.21から、最初のリリースはGo 1.N.0となりました。今日、Go 1.21言語とその初期実装であるGo 1.21.0リリースが公開されています。これらのノートは「Go 1.21」と呼ばれますが、go versionなどのツールは「go1.21.0」と報告されます(Go 1.21.1にアップグレードするまで)。
- ツールの改善点:
-
- Profile Guided Optimization(PGO)機能が一般利用可能になりました。
default.pgo
という名前のファイルがメインパッケージのディレクトリにある場合、go
コマンドはそれを使用してPGOビルドを有効にします。 go
ツールは今後の言語の後方互換性と前方互換性をサポートします。
- Profile Guided Optimization(PGO)機能が一般利用可能になりました。
- 言語の変更点:
-
- 新しい組み込み関数
min
、max
、clear
が追加されました。 - ジェネリック関数の型推論がいくつか改善され、仕様書の型推論の説明が拡張されました。
- Goプログラミングの最も一般的な落とし穴の1つに取り組む予定で、そのプレビューがGo 1.21に含まれています。これは環境変数を使用してコードで有効にできます。詳細はLoopvarExperiment wikiページを参照してください。
- 新しい組み込み関数
- 標準ライブラリの追加点:
-
- 構造化ログのための新しいlog/slogパッケージが追加されました。
- 任意の要素型のスライスに対する共通操作のための新しいslicesパッケージが追加されました。これには、一般的により高速で使いやすいソート関数も含まれています。
- 任意のキーまたは要素型のマップに対する共通操作のための新しいmapsパッケージが追加されました。
- 順序付けられた値を比較するための新しいユーティリティを提供するcmpパッケージが追加されました。
- 性能の改善点:
-
- PGOを有効にした際のパフォーマンス向上に加えて、以下のような改善があります。
- Goコンパイラ自体がPGOを有効にして再ビルドされ、ホストアーキテクチャによってはプログラムのビルドが2〜4%高速化されました。
- ガベージコレクターの調整により、一部のアプリケーションではテールレイテンシーが最大40%削減される場合があります。
- runtime/traceでトレースを収集する際のCPUコストが、amd64およびarm64で大幅に低減されました。
- 新しいWASIポート:
-
- Go 1.21には、WebAssembly System Interface(WASI)の実験的なポートが追加されました(GOOS=wasip1、GOARCH=wasm)。
- より一般的なWebAssembly(Wasm)コードの記述を容易にするために、コンパイラはWasmホストからの関数のインポートのための新しい指令
go:wasmimport
をサポートしています。
Go 1.20
[編集]Go 1.20が、2023年2月にリリースされました[8][9]。
Go 1.20では、スライスから配列への変換が可能になりました。また、unsafeパッケージには新しい関数が追加され、スライスや文字列の値を構築および分解する完全な機能が提供されるようになりました。また、新しい仕様により、構造体のフィールドと配列の要素の比較が最初の不一致で停止するようになり、厳密に比較できない型引数を持つ型パラメータを使用して、比較制約に制限された型をインスタンス化することが可能になりました。
Go 1.19
[編集]Go 1.19が、2022年8月にリリースされました[10][11]。
Go 1.19では、ツールチェーン、ランタイム、およびライブラリの実装に変更が加えられています。言語にはわずかな修正があり、既存のプログラムには影響がないです。メモリモデルも更新され、C、C ++、Java、JavaScript、Rust、Swiftなどのメモリモデルに合わせられた。Go 1.19では、sync/atomicパッケージに新しい型が導入され、atomic.Int64やatomic.Pointer[T]などのatomic値をより簡単に使用できるようになっています。Go 1の互換性を維持しており、ほとんどのGoプログラムは引き続き従前どおりにコンパイルおよび実行されることが予想されます。
Go 1.18
[編集]Go 1.18が、2022年3月にリリースされました[12]。
Go 1.18 には、型パラメータプロポーザル[13]で説明されたジェネリック機能の実装が含まれています。
以下は、最も目に付く変更点のリストです。
- 関数と型宣言の構文に型パラメータが使えるようになりました。⇒ /関数#ジェネリック関数
- パラメータ化された関数や型は、その後に角括弧で型引数のリストを記述することでインスタンス化することができます。
- 新しいトークン
~
が演算子および区切子(punctuation)に追加されました。⇒ /字句的要素#演算子と区切子 - インターフェイス型の構文では、任意の型(インターフェイスの型名だけでなく)、unionや~T型要素を埋め込むことができるようになりました。このようなインターフェースは、型制約としてのみ使用することができます。インターフェイスはメソッドと同様に型の集合を定義するようになりました。⇒ /型#インターフェース型
- 新しい事前宣言された識別子
any
は空のインターフェースの別名です。これはinterface{}
の代わりに使用することができます。 - 新しい宣言済み識別子
comparable
は==
や!=
を使って比較できる全ての型の集合を表すインターフェースです.
ジェネリックを使った実験的なパッケージが3つあり、便利かもしれません。これらのパッケージは x/exp リポジトリにあります。これらのパッケージの API は Go 1 の保証の対象外であり、ジェネリックの経験を積むにつれて変更される可能性があります。
- golang.org/x/exp/constraints
constraints.Ordered
のようなジェネリックコードに便利な制約です。- golang.org/x/exp/slices
- 任意の要素タイプのスライス上で操作するジェネリック関数のコレクションです。
- golang.org/x/exp/maps
- 任意のキーや要素タイプのマップ上で操作するジェネリック関数のコレクションです。
Go 1.18は、言語、ツールチェーン、ランタイム、ライブラリに変更があり、互換性が保たれている。最大の変更点は、ジェネリックスの導入である。ジェネリックスはバックワード互換性があるが、実際に多くの人が書き、使用して初めて本番環境で十分にテストされる。ジェネリックスの使用は推奨されるが、本番環境で使用する場合は注意が必要である。ジェネリックスにはいくつかの制限があるが、これらは将来的に改善される可能性がある。これらの変更により、Goエコシステム全体に影響があり、完全なサポートには時間がかかるだろう。
Go 1.17
[編集]Go 1.17が、2021年8月にリリースされました[14][15]。
Go 1.17は、ツールチェーン、ランタイム、およびライブラリの実装の変更が中心で、ほとんどの変更は互換性が維持されています。言語自体には3つの小さな強化があり、スライスから配列ポインタへの変換、unsafe.Add、unsafe.Sliceが追加されました。このうち、スライスから配列ポインタへの変換が実行時にpanicを引き起こす場合があるため、タイプ変換が実行時にpanicを引き起こす可能性があることを考慮する必要があります。新しいプログラムを書く場合も、以前と同様に、unsafe.Pointerの安全ルールに従う必要があります。
Go 1.16
[編集]Go 1.16が、2021年2月にリリースされました[16][17]。
Go 1.16では、ツールチェーン、ランタイム、ライブラリの実装が変更されています。Go 1の互換性を維持しながら、ほとんどのプログラムが従来通りにコンパイルおよび実行できるようになっています。言語には変更はありません。
Go 1.15
[編集]Go 1.15が、2020年8月にリリースされました[18][19]。
Go 1.15では、リンカーの大幅な改良、高いコア数での小規模オブジェクトの割り当ての改善、X.509 CommonNameの非推奨化、そして新しい埋め込みtzdataパッケージの追加が含まれています。
Go 1.14
[編集]Go 1.14が、2020年2月にリリースされました[20][21]。
Go 1.14では、オーバーラップするインターフェースの提案により、埋め込まれたインターフェースで同じ名前とシグネチャを持つメソッドを許可するようになりました。しかし、インターフェース内で宣言されたメソッドは以前と同様にユニークである必要があります。
Go 1.13
[編集]Go 1.13が、2019年2月にリリースされました[22][23]。
Go 1.13では、数字リテラルの接頭辞が変更され、バイナリ整数、8進数整数、16進数浮動小数点数、虚数リテラル、数字区切りが使用できるようになりました。さらに、符号付きシフトカウントの制限が撤廃され、制限がなくなりました。これらの変更は、コンパイラの変更によって実現されました。Go 1.13を使用するには、go.modファイルで言語バージョンを指定する必要があります。
Go 1.12
[編集]Go 1.12が、2019年2月にリリースされました[24][25]。 Go 1.12のリリースには、いくつかの新機能と改善が含まれ、Go言語のパフォーマンスやユーザビリティがさらに向上しました。以下が主な変更点です。
- 主要な新機能:
-
- Windows向けに、標準ライブラリがコントロールグループのサポートやシステムコールの改善により、性能向上と安定性が強化されました。
- macOS向けの新しいサポートとして、ヒープメモリ使用量の削減や効率化が進められました。
- パフォーマンスの改善点:
-
- 文字列操作の最適化が行われ、
strings.Trim
やstrings.Index
のパフォーマンスが向上しました。 - 並列ガベージコレクションが改良され、メモリ管理の効率が向上しています。
- コンパイラの境界チェックが一部のパターンで自動的に省略されるようになり、コード生成の効率がさらに向上しました。
- 文字列操作の最適化が行われ、
- デバッグ機能の改善:
-
- より正確な変数位置とスタック情報の提供により、デバッグ体験が改善されています。
- 新たにDWARF生成の機能が拡充され、特に最適化コードにおいて、デバッグ情報の信頼性が高まりました。
- ランタイムの改善:
-
- Windows上で、64ビットプロセスのアドレス空間使用が最適化され、より多くのメモリを使用可能になりました。
- Goランタイムのシグナルハンドリングが強化され、システムシグナルの処理能力が向上しました。
- 標準ライブラリの改善:
-
crypto/x509
パッケージで、証明書の検証がmacOSのシステム証明書ストアを使用するようになり、macOSでの信頼性が向上しました。net/http
において、HTTP/2の接続管理が改善され、特に大量接続環境での安定性が増しました。os
パッケージのProcess.Signal
がWindowsでも利用可能となり、Windows上のプロセス管理機能が強化されました。
- ツールの改善:
-
go test
コマンドに-json
フラグが追加され、テスト結果をJSON形式で出力できるようになりました。- goコマンドが
go.sum
ファイルを自動的に更新し、依存関係の信頼性が向上しています。 gofmt
において、特定のコードパターンの整形が改良され、より一貫したコードスタイルが保たれます。
また、OpenBSD 6.4以降、macOS 10.11 El Capitan以降、またはWindows 7以降が必要となり、これらのOSの以前のバージョンのサポートが終了しました。リリースノートでは、Go 1の互換性は維持されており、ほとんどのGoプログラムは以前と同様に動作すると述べられています。
Go 1.11
[編集]Go 1.11が、2018年8月にリリースされました[26][27]。 Go 1.11のリリースでは、いくつかの重要な新機能と改善が含まれています。最も注目すべき変更点は以下です。
- 主要な新機能:
-
- モジュールサポートの実験的な導入により、GOPATHに依存しない開発が可能になりました。バージョン管理と依存関係管理が統合され、より信頼性の高いビルドが実現できます。
- WebAssembly(js/wasm)の実験的なポートが追加され、syscall/jsパッケージを通じてJavaScriptとの連携が可能になりました。
- RISCVアーキテクチャ向けのGOARCH値("riscv"と"riscv64")が予約されました。
- パフォーマンスの改善点:
-
- マップのクリア操作が最適化され、
for k := range m { delete(m, k) }
のようなコードが効率的に実行されるようになりました。 - スライス拡張の
append(s, make([]T, n)...)
が最適化されました。 - コンパイラの境界チェックと分岐除去が大幅に改善され、より効率的なコードが生成されるようになりました。
- マップのクリア操作が最適化され、
- デバッグ機能の改善:
-
- 最適化されたバイナリのデバッグ情報が大幅に改善され、変数位置情報、行番号、ブレークポイント位置がより正確になりました。
- DWARFセクションがデフォルトで圧縮されるようになりました。
- デバッガー内からのGo関数呼び出しが実験的にサポートされました。
- ランタイムの改善:
-
- スパースヒープレイアウトの採用により、Goヒープサイズの制限(従来は512GiB)が撤廃されました。
- macOSとiOSで、カーネルの直接呼び出しの代わりにlibSystem.dylibを使用するように変更され、将来のOSバージョンとの互換性が向上しました。
- 標準ライブラリの改善:
-
crypto/cipher
パッケージに、非標準のタグ長をサポートするGCM実装が追加されました。net/http
のTransport
型に、ホストごとの最大接続数を制限するMaxConnsPerHost
オプションが追加されました。os
パッケージに、ユーザー固有のキャッシュディレクトリを取得するUserCacheDir
関数が追加されました。
- ツールの改善:
-
- 環境変数
GOFLAGS
が導入され、goコマンドのデフォルトフラグを設定できるようになりました。 - godocのWebサーバーが、APIの新機能がどのGoバージョンで導入されたかを表示するようになりました。
- 環境変数
また、OpenBSD 6.2以降、macOS 10.10 Yosemite以降、またはWindows 7以降が必要となり、これらのOSの以前のバージョンのサポートが終了しました。リリースノートでは、Go 1の互換性は維持されており、ほとんどのGoプログラムは以前と同様に動作すると述べられています。
脚註
[編集]- ^ “Introduction¶”. The Go Programming Language Specification Language version go1.23 (June 13, 2024). The Go website. (June 13, 2024) .
- ^ Go 1.23 Release Notes - The Go Programming Language. (2024/08/13) 2024年11月13日閲覧。.
- ^ Go 1.23 is released! - The Go Programming Language. (2024/08/13) 2024年11月13日閲覧。.
- ^ Go 1.22 Release Notes - The Go Programming Language. (2024/02/06) 2024年2月11日閲覧。.
- ^ Go 1.22 is released! - The Go Programming Language. (2024/02/06) 2024年2月11日閲覧。.
- ^ Go 1.21 Release Notes - The Go Programming Language. (2023/08/08) 2023年11月28日閲覧。.
- ^ [https://go.dev/blog/go1.21 Go 1.21 is released! - The Go Programming Language 5]. (2023/08/08) 2023年11月28日閲覧。.
- ^ Go 1.20 Release Notes - The Go Programming Language. (2023/02/01) 2023年3月5日閲覧。.
- ^ Go 1.20 is released! - The Go Programming Language. (2023/02/01) 2023年3月5日閲覧。.
- ^ Go 1.19 Release Notes - The Go Programming Language. (2022/08/02) 2022年8月4日閲覧。.
- ^ Go 1.19 is released! - The Go Programming Language. (2022/08/02) 2022年8月4日閲覧。.
- ^ Go 1.18 Release Notes - The Go Programming Language. (2022/03/10) 2022年8月4日閲覧。.
- ^ Type Parameters Proposal 2021年9月30日閲覧。.
- ^ Go 1.17 Release Notes - The Go Programming Language. (2021/08/16) 2023年3月6日閲覧。.
- ^ Go 1.17 is released! - The Go Programming Language. (2021/08/16) 2023年3月6日閲覧。.
- ^ Go 1.16 Release Notes - The Go Programming Language. (2021/02/16) 2023年3月6日閲覧。.
- ^ Go 1.16 is released! - The Go Programming Language. (2021/02/16) 2023年3月6日閲覧。.
- ^ Go 1.15 Release Notes - The Go Programming Language. (2020/08/11) 2023年3月12日閲覧。.
- ^ Go 1.15 is released! - The Go Programming Language. (2020/08/11) 2023年3月12日閲覧。.
- ^ Go 1.14 Release Notes - The Go Programming Language. (2020/02/25) 2023年3月12日閲覧。.
- ^ Go 1.14 is released! - The Go Programming Language. (2020/02/25) 2023年3月12日閲覧。.
- ^ Go 1.13 Release Notes - The Go Programming Language. (2019/09/03) 2023年3月12日閲覧。.
- ^ Go 1.13 is released! - The Go Programming Language. (2019/09/03) 2023年3月12日閲覧。.
- ^ Go 1.12 Release Notes - The Go Programming Language. (2019/02/25) 2024年11月13日閲覧。.
- ^ Go 1.12 is released! - The Go Programming Language. (2019/02/25) 2024年11月13日閲覧。.
- ^ Go 1.11 Release Notes - The Go Programming Language. (2018/08/24) 2024年11月13日閲覧。.
- ^ Go 1.11 is released! - The Go Programming Language. (2018/08/24) 2024年11月13日閲覧。.
参考文献
[編集]- The Go Programming Language Specification. The Go website. (JJune 13, 2024) .