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.24
Go 1.24が、2025年2月にリリースされました[2][3]。
Go 1.24のリリースでは、いくつかの重要な新機能と改善が含まれています。最も注目すべき変更点は以下です。
- 言語の変更点:
- ジェネリック型エイリアスが完全にサポートされるようになりました。これにより、型エイリアスに型パラメータを設定できるようになり、既存の型を制約付きで再定義することが可能になりました。たとえば
type VectorAlias[T any] = Vector[T]
のような定義ができます。この機能は Go 1.23 では実験的な機能(GOEXPERIMENT=aliastypeparams)でしたが、Go 1.24で正式にサポートされました。
- ジェネリック型エイリアスが完全にサポートされるようになりました。これにより、型エイリアスに型パラメータを設定できるようになり、既存の型を制約付きで再定義することが可能になりました。たとえば
- 新しい標準パッケージ:
- crypto/mlkem:ML-KEM-768とML-KEM-1024を実装したパッケージ。
- crypto/hkdf:HMAC-based Extract-and-Expand key derivation function (HKDF) を実装したパッケージ。
- crypto/pbkdf2:password-based key derivation function (PBKDF2) を実装したパッケージ。
- crypto/sha3:SHA-3ハッシュ関数とSHAKE/cSHAKE extendable-output functionsを実装したパッケージ。
- weak:弱参照を提供するパッケージ。
- testing/synctest:並行コードのテストをサポートする実験的なパッケージ(GOEXPERIMENT=synctestが必要)。
- パフォーマンスの改善点:
- Swiss Tablesベースの新しいマップ実装により、2-3%のCPUオーバーヘッドが削減。
- 小さなオブジェクトのメモリ割り当ての効率化。
- 新しいランタイム内部ミューテックス実装。
- ツールの改善:
- go.modファイルでツール依存関係を追跡できるようになりました。
- go buildとgo installに -json フラグが追加され、構造化されたJSON出力が可能に。
- go vetに新しいtestsアナライザーが追加され、テストの一般的な間違いを検出可能に。
- セキュリティの改善:
- FIPS 140-3コンプライアンスのための新しいメカニズムが追加。
- TLSサーバーがEncrypted Client Hello (ECH)をサポート。
- RSAキーは1024ビット未満のキーサイズでエラーを返すように変更。
- プラットフォームサポートの変更:
- Linuxはカーネルバージョン3.2以降が必要になりました。
- Go 1.24はmacOS 11 Big Surをサポートする最後のバージョンとなります。
- Windows 32-bit ARM (windows/arm)は「broken」とマークされました。
また、1.23でサポートされた"for-range"ループのイテレータ機能を活用し、bytes/stringsパッケージに新しいイテレータ関数(Lines、SplitSeq、SplitAfterSeq、FieldsSeq、FieldsFuncSeq)が追加されました。os.Root型による特定ディレクトリ内でのファイルシステム操作が可能になり、testing.B.Loopメソッドにより、ベンチマークの記述がより簡単で安全になっています。
Go 1.23
Go 1.23が、2024年8月にリリースされました[4][5]。 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月にリリースされました[6][7]。 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月にリリースされました[8][9]。
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月にリリースされました[10][11]。
Go 1.20では、スライスから配列への変換が可能になりました。また、unsafeパッケージには新しい関数が追加され、スライスや文字列の値を構築および分解する完全な機能が提供されるようになりました。また、新しい仕様により、構造体のフィールドと配列の要素の比較が最初の不一致で停止するようになり、厳密に比較できない型引数を持つ型パラメータを使用して、比較制約に制限された型をインスタンス化することが可能になりました。
Go 1.19
Go 1.19が、2022年8月にリリースされました[12][13]。
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月にリリースされました[14]。
Go 1.18 には、型パラメータプロポーザル[15]で説明されたジェネリック機能の実装が含まれています。
以下は、最も目に付く変更点のリストです。
- 関数と型宣言の構文に型パラメータが使えるようになりました。⇒ /関数#ジェネリック関数
- パラメータ化された関数や型は、その後に角括弧で型引数のリストを記述することでインスタンス化することができます。
- 新しいトークン
~
が演算子および区切子(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月にリリースされました[16][17]。
Go 1.17は、ツールチェーン、ランタイム、およびライブラリの実装の変更が中心で、ほとんどの変更は互換性が維持されています。言語自体には3つの小さな強化があり、スライスから配列ポインタへの変換、unsafe.Add、unsafe.Sliceが追加されました。このうち、スライスから配列ポインタへの変換が実行時にpanicを引き起こす場合があるため、タイプ変換が実行時にpanicを引き起こす可能性があることを考慮する必要があります。新しいプログラムを書く場合も、以前と同様に、unsafe.Pointerの安全ルールに従う必要があります。
Go 1.16
Go 1.16が、2021年2月にリリースされました[18][19]。
Go 1.16では、ツールチェーン、ランタイム、ライブラリの実装が変更されています。Go 1の互換性を維持しながら、ほとんどのプログラムが従来通りにコンパイルおよび実行できるようになっています。言語には変更はありません。
Go 1.15
Go 1.15が、2020年8月にリリースされました[20][21]。
Go 1.15では、リンカーの大幅な改良、高いコア数での小規模オブジェクトの割り当ての改善、X.509 CommonNameの非推奨化、そして新しい埋め込みtzdataパッケージの追加が含まれています。
Go 1.14
Go 1.14が、2020年2月にリリースされました[22][23]。
Go 1.14では、オーバーラップするインターフェースの提案により、埋め込まれたインターフェースで同じ名前とシグネチャを持つメソッドを許可するようになりました。しかし、インターフェース内で宣言されたメソッドは以前と同様にユニークである必要があります。
Go 1.13
Go 1.13が、2019年2月にリリースされました[24][25]。
Go 1.13では、数字リテラルの接頭辞が変更され、バイナリ整数、8進数整数、16進数浮動小数点数、虚数リテラル、数字区切りが使用できるようになりました。さらに、符号付きシフトカウントの制限が撤廃され、制限がなくなりました。これらの変更は、コンパイラの変更によって実現されました。Go 1.13を使用するには、go.modファイルで言語バージョンを指定する必要があります。
Go 1.12
Go 1.12が、2019年2月にリリースされました[26][27]。 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月にリリースされました[28][29]。 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プログラムは以前と同様に動作すると述べられています。
Go 1.10
Go 1.10が、2018年2月にリリースされました[30][31]。 Go 1.10のリリースでは、開発体験を大幅に向上させる複数の重要な改善が含まれています。最も注目すべき変更点は以下です。
- ビルドシステムの大幅改善:
- ビルドキャッシュの導入により、最近ビルドしたパッケージが自動的にキャッシュされ、ビルド時間が大幅に短縮されました。
- テスト結果のキャッシュ化により、変更のないテストは再実行せずにキャッシュされた結果を使用するようになりました。
go test
時にgo vet
が自動実行され、テスト前にコードの問題を検出できるようになりました。go install
コマンドが、コマンドラインで指定されたパッケージのみをインストールするように変更されました。
- cgoのセキュリティ強化と機能拡張:
- cgoの
#cgo CFLAGS
などで指定できるコンパイラオプションが安全なもののみに制限され、-fplugin
などの危険なオプションは使用できなくなりました。 - Go文字列値へのC言語からの直接アクセスが可能になり、
_GoString_
型、_GoStringLen
、_GoStringPtr
関数が追加されました。 - CのtypedefがGoの型エイリアスとして実装され、
C.X
とC.Y
を相互に使用できるようになりました。
- cgoの
- パフォーマンスの改善点:
- ガベージコレクタが割り当て遅延への影響を軽減するよう改善されました。
- コンパイラの最適化によりコード生成品質が向上し、サポートされている全アーキテクチャで性能が向上しました。
- スタックトレースから暗黙のラッパー関数(
<autogenerated>
マーク)が除外され、より読みやすくなりました。
- ツールの改善:
go doc
コマンドが、型Tを返すスライスや*Tを返す関数も型Tの表示に含めるようになりました。go test
に-failfast
フラグが追加され、テスト失敗時に残りのテストを停止できるようになりました。go test -json
フラグが追加され、機械読み取り可能なJSON形式でテスト結果を出力できるようになりました。go get
コマンドでFossilソースコードリポジトリがサポートされました。
- ランタイムの改善:
LockOSThread
とUnlockOSThread
の呼び出しがネストをサポートするようになりました。GOMAXPROCS
の制限が撤廃されました(以前は1024が上限)。GOROOT
関数が、環境変数が設定されていない場合にプログラムのコンパイル時の値を使用するようになりました。
- 標準ライブラリの改善:
strings
パッケージに新しいBuilder
型が追加され、文字列構築時のメモリ効率が向上しました。math
パッケージにRound
、RoundToEven
、Erfinv
、Erfcinv
関数が追加されました。net/url
のResolveReference
が複数の先頭スラッシュを保持するように修正され、RFC 3986に準拠しました。bytes
パッケージのFields
、Split
系関数が、返すサブスライスの容量を長さと同じに設定するようになり、メモリ効率が向上しました。archive/tar
とarchive/zip
でより多くのヘッダー形式や時刻エンコーディングがサポートされました。
- デバッグ機能の改善:
- バイナリ内のDWARFデバッグ情報が改善され、定数値の記録、より正確な行番号情報、パッケージ単位でのコンパイル単位の表現が実現されました。
- 各種ビルドモードがより多くのシステムに対応し、
c-shared
、pie
、plugin
モードの対応プラットフォームが拡張されました。
- アセンブラの拡張:
- ARM 32ビット、ARM 64ビット、PowerPC 64ビット、S390X、X86 64ビットアーキテクチャで多数の新しい命令がサポートされました。
- 特にX86 64ビットでは、AVX、AVX2、BMI、BMI2、F16C、FMA3、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2などの拡張命令セットを含む359の新命令が追加されました。
- ソースコードフォーマットの変更:
gofmt
のデフォルトフォーマットに軽微な変更があり、3つのインデックスを持つスライス式と単一行のインターフェースリテラルの表示が改善されました。
Go 1.9
Go 1.9が、2017年8月にリリースされました[32][33]。 Go 1.9のリリースでは、言語、ツール、ランタイム、標準ライブラリに多くの変更と改善が含まれています。主な変更点は以下の通りです。
- 言語の変更点:
- 型エイリアス: パッケージ間で型を移動する際などに、段階的なコードの修正をサポートするための型エイリアスが導入されました。
type T1 = T2
- の形式で宣言することで、既存の型 T2 に別の名前 T1 を与えることができます。
- 浮動小数点演算の融合: 言語仕様が更新され、実装が浮動小数点演算(例えば、積和演算)を融合することが許可される条件が定義されました。中間結果の丸めを強制したい場合は、float64(x*y) + z のように明示的な型変換が必要です。
- 型エイリアス: パッケージ間で型を移動する際などに、段階的なコードの修正をサポートするための型エイリアスが導入されました。
- 新しい標準パッケージ:
- math/bits: 符号なし整数のビット操作(カウント、操作など)のための最適化された実装を提供する新しいパッケージが追加されました。可能な場合、CPUの特殊な命令が利用されます。
- パフォーマンスの改善点:
- 並列コンパイル: パッケージ内の関数のコンパイルが並列化され、マルチコア環境でのビルド時間が改善されました。この機能はデフォルトで有効ですが、環境変数 GO19CONCURRENTCOMPILATION=0 を設定することで無効にできます。
- ガベージコレクション: ストップザワールド型のガベージコレクションを引き起こしていたライブラリ関数 (runtime.GC, debug.SetGCPercent, debug.FreeOSMemory) が、呼び出し元のゴルーチンのみをブロックする並行ガベージコレクションに変更されました。
- ツールの改善:
- Vendorディレクトリのマッチング: go test などのパッケージ名を引数に取るツールにおいて、./... が vendor ディレクトリ内のパッケージをマッチしなくなりました。vendor ディレクトリをマッチさせるには、./vendor/.... を使用する必要があります。
- GOROOTの移動: go tool は、実行されたパスからGoのインストールツリーのルートを特定するようになりました。これにより、Goのインストールディレクトリ全体を移動した場合でも、go tool が通常通り動作するはずです。
- go test -list: テスト、ベンチマーク、またはExampleの名前を正規表現でフィルタリングしてリスト表示する -list フラグが go test コマンドに追加されました。
- go env -json: 環境変数をJSON形式で出力する -json フラグが go env コマンドに追加されました。
- その他の注目すべき変更点:
- sync.Map: 並行アクセスに対応した新しいマップ型 sync.Map が追加されました。読み込み、書き込み、削除操作は償却定数時間で行われます。
- testing.Helper: testing.T および testing.B に Helper メソッドが追加されました。このメソッドを呼び出すと、エラー報告などでファイル名と行番号が表示される際に、ヘルパー関数自身ではなく、ヘルパー関数を呼び出した箇所の情報が表示されるようになります。
- timeパッケージ: time パッケージは、各 Time 値に透過的に単調時間(monotonic time)を追跡するようになり、壁時計の調整があっても二つの Time 値間の経過時間を安全に計算できるようになりました。
- runtime.CallersFrames: インライン化されたフレームを含むコールスタックの情報を正確に取得するために、runtime.Callers の結果を直接検査するのではなく、runtime.CallersFrames を使用することが推奨されるようになりました。
- runtime/pprof: runtime/pprof パッケージで生成されるプロファイルにシンボル情報が含まれるようになり、プロファイルを生成したバイナリなしで go tool pprof で表示できるようになりました。また、プロファイルレコードにラベルを追加する機能も追加されました。
Go 1.9には、上記以外にも多くの追加、改善、および修正が含まれています。詳細については、公式のリリースノートを参照してください。
Go 1.8
Go 1.8が、2017年2月にリリースされました[34][35]。 Go 1.8のリリースでは、ツールチェーン、ランタイム、およびライブラリの実装に多くの変更が含まれています。主な変更点は以下の通りです。
- 言語の変更点:
- 構造体型の変換: Go 1.8以降、構造体間の明示的な型変換において、タグが無視されるようになりました。タグのみが異なる2つの構造体は、相互に変換可能です。
- 浮動小数点定数の指数: 言語仕様が更新され、実装が浮動小数点定数で最大16ビットの指数をサポートすることが要求されるようになりました。ただし、"gc" と gccgo コンパイラは、どちらも32ビットの指数をサポートしています。
- ポート:
- 32-bit MIPSのサポート: Linux上で、big-endian (linux/mips) と little-endian (linux/mipsle) の両方のマシンで、FPUまたはカーネルFPUエミュレーションを備えたMIPS32r1命令セットを実装する32-bit MIPSがサポートされるようになりました。
- ツール:
- アセンブラ: 64-bit x86システム用に、VBROADCASTSD, BROADCASTSS, MOVDDUP, MOVSHDUP, MOVSLDUP, VMOVDDUP, VMOVSHDUP, VMOVSLDUPなどの命令が追加されました。
- Yacc: yaccツールは削除されました。
- Fix: fixツールに、"golang.org/x/net/context" から "context" へimportを変更する "context" fixが追加されました。
- Pprof: pprofツールは、"https+insecure" URLスキームを使用して、TLSサーバーをプロファイルし、証明書の検証をスキップできるようになりました。
- Trace: traceツールに、実行トレースからpprof互換のブロッキングおよびレイテンシプロファイルを生成するための -pprof フラグが追加されました。
- Vet: Vetは、いくつかの点でより厳密になり、以前に誤検出を引き起こしていた箇所ではより緩くなりました。
- コンパイラツールチェーン:
- SSAバックエンド: 64-bit x86システム用の新しいコンパイラバックエンドが導入されました。このバックエンドは、よりコンパクトで効率的なコードを生成し、境界チェックの排除などの最適化のためのより良いプラットフォームを提供します。
- コンパイラとリンカの最適化: コンパイラとリンカが最適化され、Go 1.7よりも高速に実行されるようになりました。
- Cgo:
- Goツールは、make.bash中に設定されたCGO_ENABLED環境変数の値を記憶し、デフォルトですべての将来のコンパイルに適用するようになりました。
- デフォルトのGOPATH:
- GOPATH環境変数が設定されていない場合、デフォルト値を持つようになりました。Unixでは$HOME/go、Windowsでは%USERPROFILE%/goがデフォルトです。
- Go get:
- "go get"コマンドは、-insecureフラグが使用されているかどうかに関係なく、HTTPプロキシ環境変数を常に尊重するようになりました。
- Go bug:
- 新しい "go bug" コマンドは、現在のシステムに関する情報が事前に入力された状態で、GitHubでバグレポートを開始します。
- Go doc:
- "go doc" コマンドは、godocの動作に従い、定数と変数をその型でグループ化するようになりました。
- プラグイン:
- Goは、Goで記述されたプラグインを生成するための "plugin" ビルドモードと、実行時にそのようなプラグインをロードするための新しい plugin パッケージによる、プラグインの初期サポートを提供するようになりました。
- ランタイム:
- 引数の活性: ガベージコレクタは、関数全体の引数をライブとは見なしなくなりました。
- 並行マップの誤用: Go 1.6で、マップの並行誤用の軽量でベストエフォートな検出が追加されました。このリリースでは、マップへの並行書き込みと反復処理を行うプログラムの検出がサポートされ、その検出器が改善されました。
- パフォーマンス:
- ガベージコレクションの一時停止が大幅に短縮され、通常は100マイクロ秒未満、多くの場合10マイクロ秒程度になりました。
- deferred関数呼び出しのオーバーヘッドが約半分に削減されました。
- GoからCへの呼び出しのオーバーヘッドが約半分に削減されました。
- 標準ライブラリ:
- Examples: 多くのパッケージに例が追加されました。
- Sort: sortパッケージに、less関数を指定してスライスをソートするための便利な関数Sliceが含まれるようになりました。
- HTTP/2 Push: net/httpパッケージに、HandlerからHTTP/2サーバープッシュを送信するメカニズムが含まれるようになりました。
- HTTPサーバーの正常シャットダウン: HTTPサーバーは、新しいServer.Shutdownメソッドを使用した正常シャットダウンと、新しいServer.Closeメソッドを使用した突然のシャットダウンをサポートするようになりました。
- コンテキストのサポート: context.Contextの標準ライブラリへの採用を継続し、Go 1.8は、既存のパッケージへのコンテキストサポートを追加しました。
- Mutex競合プロファイリング: ランタイムとツールが、競合するmutexのプロファイリングをサポートするようになりました。
Go 1.8には、上記以外にも多くの追加、改善、および修正が含まれています。詳細については、公式のリリースノートを参照してください。
Go 1.7
Go 1.7が、2016年8月にリリースされました[36][37]。 主な変更点は以下の通りです。
- 主な変更点
- 言語仕様: 終了ステートメントの定義を明確化(既存の挙動を正式化)
- パフォーマンス: x86-64向け新しいコンパイラバックエンドで5-35%の性能向上
- 標準ライブラリ:
context
パッケージが標準ライブラリに昇格net/http/httptrace
パッケージ追加- テスト階層構造をサポート(サブテスト/サブベンチマーク)
- ツールチェーン:
- ビルド時間の改善
- バイナリサイズの削減(20-30%減少することも)
- ベンダリングサポートが正式機能に
- ポート:
- macOS 10.12 Sierraサポート追加
- Linux on z Systems(s390x)の実験的サポート追加
- 互換性
Go 1の互換性保証を維持。ほとんどのGoプログラムは変更なしで動作する見込み。
- その他の注目点
- ガベージコレクションの一時停止時間が短縮
- 多数の標準ライブラリで10%以上の性能改善
- Unicode 9.0サポート
- WindowsでのメモリOS返還サポート
- 実行トレースの収集オーバーヘッドが大幅改善(400%→25%)
このリリースは主にツールチェーン、ランタイム、ライブラリの実装改善に焦点を当てています。
脚註
- ↑ “Introduction¶”. The Go Programming Language Specification Language version go1.23 (June 13, 2024). The Go website. (June 13, 2024) .
- ↑ Go 1.24 Release Notes - The Go Programming Language. (2024/02/11) 2024年2月23日閲覧。.
- ↑ Go 1.24 is released! - The Go Programming Language. (2024/02/11) 2024年2月23日閲覧。.
- ↑ 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日閲覧。.
- ↑ Go 1.10 Release Notes - The Go Programming Language. (2018/02/16) 2025年5月20日閲覧。.
- ↑ Go 1.10 is released - The Go Programming Language. (2018/02/16) 2025年5月20日閲覧。.
- ↑ “Go 1.9 Release Notes - The Go Programming Language”. 2025年5月20日閲覧。
- ↑ “Go 1.9 is released - The Go Blog” (2017年8月24日). 2025年5月20日閲覧。
- ↑ “Go 1.8 Release Notes - The Go Programming Language”. 2025年5月20日閲覧。
- ↑ “Go 1.8 is released - The Go Blog” (2017年2月16日). 2025年5月20日閲覧。
- ↑ “Go 1.7 Release Notes - The Go Programming Language”. 2025年5月20日閲覧。
- ↑ “Go 1.7 is released - The Go Blog” (2016年8月15日). 2025年5月20日閲覧。
参考文献
- The Go Programming Language Specification. The Go website. (JJune 13, 2024) .
下位階層のページ
- 0
- Cのif-elseのエラーパターン解消に関するGoの選択
- EBNF
- Goのコードでgoのバージョンを調べる方法
- Goのプログラムがどんなアセンブリにコンパイルされるか?
- HTTP
- Hypot
- Keywords
- Predeclared identifiers
- Standard library
- Zero value
- any
- append
- bool
- break
- byte
- cap
- case
- cgoでGoのコードからCの関数を利用する
- chan
- clear
- comparable
- complex128
- complex64
- const
- continue
- core type
- default
- defer
- defer,panicとrecover
- else
- else if
- error
- fallthrough
- false
- float32
- float64
- for
- func
- go
- goto
- if
- import
- int
- int16
- int32
- int64
- int8
- interface
- iota
- map
- named type
- nil
- package
- range
- return
- rune
- select
- string
- struct
- switch
- true
- type
- type literal
- uint
- uint16
- uint32
- uint64
- uint8
- uintptr
- underlying type
- var
- イテレータ
- エラー
- キーワードと宣言済み識別子
- クロスコンパイル
- コードギャラリー
- ジェネリクス
- ソースコードの表現方法
- パッケージ
- ファイル入出力
- ブロック・宣言とスコープ
- プログラムの初期化と実行
- マップ
- メソッド
- メソッドとインターフェース
- メソッドチェイン
- 並行処理
- 主要な標準インターフェース
- 再帰的関数呼出し
- 型
- 型と値の特性
- 変数
- 字句的要素
- 定数と変数
- 実行の方法
- 式
- 改廃された技術
- 数リテラルの精度と型
- 文
- 文法の概要
- 条件分岐と繰り返し
- 構造体
- 標準ライブラリー
- 環境構築
- 算術演算と数学関数
- 配列とスライス
- 関数