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]。主な変更点は以下の通りです。
- 言語の変更点
- 新しい型パラメータ機能により、ジェネリック型の記述がより柔軟になり、型安全性を保ちながら、より一般的な関数やデータ構造を作成できます。
- 新しい
defer
機能が追加され、複数のdefer
ステートメントを効率的に管理する方法が提供されます。
- パフォーマンスの改善点
- Goランタイムのガーベジコレクションアルゴリズムが改良され、GCのオーバーヘッドが10-15%削減されました。
- JITコンパイラの機能が拡張され、特定のケースで最大20%のパフォーマンス向上が見込まれます。
- 標準ライブラリの追加
- 新しい
context
パッケージの機能強化により、コンテキストのキャンセルやタイムアウトの管理がより直感的になりました。 sync
パッケージにMap
型が追加され、スレッドセーフなマップの使用が可能になりました。encoding/json
パッケージには新しいDecoder
型が追加され、大きなJSONデータをストリームとして処理する際のメモリ効率が改善されました。
Go 1.22
[編集]Go 1.22が、2024年2月にリリースされました[4][5]。 Go 1.22のリリースでは、いくつかの重要な新機能と改善が含まれています。最も注目すべき変更点は以下です。
- 言語の変更点:
- 長らく問題視されてきた「for」ループの落とし穴が解決されました。Go 1.22以降、ループ変数がイテレーション間で意図せず共有される問題が解消されました。
- 整数の範囲に対する
range
のサポートが追加されました。これにより、整数をカウントダウンするプログラムなどで簡潔に記述できるようになります。
- パフォーマンスの改善点:
- Goランタイムのメモリ最適化により、CPUパフォーマンスが1-3%向上し、ほとんどのGoプログラムのメモリオーバーヘッドが約1%削減されました。
- Go 1.21で導入されたプロファイル誘導最適化(PGO)の機能が引き続き改善されています。PGOを有効にすることで、より多くのインターフェースメソッド呼び出しの静的ディスパッチが可能になり、ほとんどのプログラムで2-14%の改善が見られます。
- 標準ライブラリの追加:
- 新しいmath/rand/v2パッケージが追加され、よりクリーンで一貫性のあるAPIが提供されます。
- net/http.ServeMuxのパターンがメソッドとワイルドカードを受け入れるようになりました。例えば、GET /task/{id}/というパターンはGETリクエストのみを受け入れ、{id}セグメントの値を取得できるようになりました。
また、database/sqlパッケージにはNull[T]型が追加され、nullableカラムをスキャンする方法が提供されます。slicesパッケージには複数のスライスを連結するConcat関数が追加されました。
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
ツールは今後の言語の後方互換性と前方互換性をサポートします。
- 言語の変更点:
- 新しい組み込み関数
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 1の互換性を維持しながら、ほとんどのプログラムが従来通りにコンパイルおよび実行できるようになっています。言語には変更はありません。
脚註
[編集]- ^ “Introduction¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
- ^ Go 1.23 Release Notes - The Go Programming Language. (2024/08/13) 2024年8月15日閲覧。.
- ^ Go 1.23 is released! - The Go Programming Language. (2024/08/13) 2024年8月15日閲覧。.
- ^ Go 1.22 Release Notes - The Go Programming Language. (2024/02/06) 2024年2月11日閲覧。.
- ^ Go 1.21 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) 2023年3月12日閲覧。.
- ^ Go 1.12 is released! - The Go Programming Language. (2019/02/25) 2023年3月12日閲覧。.
参考文献
[編集]- The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
- Go プログラミング言語仕様. (2021/02/10) .