Go 1とGoプログラムの未来
はじめに
Goバージョン1(略してGo 1)のリリースは、言語の開発における主要な節目です。Go 1は、Goで書かれたプログラムやプロジェクトの成長のための安定したプラットフォームです。
Go 1は2つのことを定義しています。第一に、言語の仕様。第二に、コアAPI群、つまりGoライブラリの「標準パッケージ」の仕様です。Go 1リリースには、2つのコンパイラスイート(gcとgccgo)とコアライブラリそのものという形で、それらの実装が含まれています。
Go 1の仕様に準拠して書かれたプログラムは、その仕様の期間中、変更なしでコンパイルおよび実行され続けることが意図されています。不特定の時点でGo 2の仕様が登場するかもしれませんが、それまでは、今日動作するGoプログラムは、将来のGo 1の「ポイント」リリース(Go 1.1、Go 1.2など)が登場しても動作し続けるはずです。
互換性はソースレベルです。コンパイルされたパッケージのバイナリ互換性は、リリース間で保証されません。ポイントリリース後、Goソースは新しいリリースにリンクするために再コンパイルする必要があります。
APIは、新しいパッケージや機能を取得して成長する可能性がありますが、既存のGo 1コードを破壊する方法ではありません。
期待
時間の経過とともに、ほとんどのプログラムがこの互換性を維持すると予想されますが、将来の変更がどのプログラムも破壊しないことを保証することは不可能です。このドキュメントは、将来のGo 1ソフトウェアの互換性に対する期待を設定する試みです。今日コンパイルして実行されるプログラムが、将来のポイントリリース後にそうできなくなる方法はいくつかあります。それらはすべてありそうもないですが、記録する価値があります。
- セキュリティ。仕様または実装におけるセキュリティ上の問題が明らかになり、その解決に互換性を破る必要がある場合があります。そのようなセキュリティ上の問題に対処する権利を留保します。
- 未指定の動作。Goの仕様は、言語のほとんどのプロパティについて明示的にしようとしますが、未定義の側面もいくつかあります。そのような未指定の動作に依存するプログラムは、将来のリリースで壊れる可能性があります。
- 仕様エラー。仕様の矛盾または不完全性に対処する必要が生じた場合、問題の解決は既存のプログラムの意味または合法性に影響を与える可能性があります。私たちは、実装の更新を含め、そのような問題に対処する権利を留保します。セキュリティ上の問題を除き、仕様に対する互換性のない変更は行われません。
- バグ。コンパイラまたはライブラリに仕様に違反するバグがある場合、そのバグのある動作に依存するプログラムは、バグが修正されると壊れる可能性があります。私たちはそのようなバグを修正する権利を留保します。
- 構造体リテラル。後のポイントリリースで機能を追加するために、APIの公開された構造体にフィールドを追加する必要がある場合があります。これらの型の値を作成するためにキーなし構造体リテラル(`pkg.T{3, "x"}`など)を使用するコードは、そのような変更後にコンパイルに失敗します。ただし、キー付きリテラル(`pkg.T{A: 3, B: "x"}`)を使用するコードは、そのような変更後もコンパイルされ続けます。私たちは、キー付き構造体リテラルが互換性を維持できるように、そのようなデータ構造を更新しますが、キーなしリテラルはコンパイルに失敗する可能性があります。(ネストされたデータ構造やインターフェースを含む、より複雑なケースもありますが、それらも同じ解決策です。)したがって、別のパッケージで型が定義されている複合リテラルには、キー付き表記を使用することをお勧めします。
- メソッド。構造体フィールドと同様に、非インターフェース型にメソッドを追加する必要がある場合があります。型が別の型とともに構造体に埋め込まれている場合など、特定の状況では、新しいメソッドの追加が、他の埋め込み型の既存のメソッドとの競合を引き起こすことにより、構造体を破壊する可能性があります。この稀なケースから保護することはできず、そのような場合でも互換性を保証しません。
- ドットインポート。プログラムが`import . "path"`を使用して標準パッケージをインポートする場合、将来のリリースでインポートされたパッケージに定義された追加の名前が、プログラムに定義された他の名前と競合する可能性があります。テスト以外での`import .`の使用は推奨せず、使用すると将来のリリースでプログラムがコンパイルに失敗する可能性があります。
- `unsafe`パッケージの使用。`
unsafe`をインポートするパッケージは、Go実装の内部プロパティに依存する場合があります。私たちは、そのようなプログラムを破壊する可能性のある実装変更を行う権利を留保します。
もちろん、これらの可能性すべてについて、発生した場合は、既存のコードに影響を与えることなく、仕様、コンパイラ、またはライブラリを更新するために、可能な限り努力します。
これらの考慮事項は、後続のポイントリリースにも適用されます。たとえば、Go 1.2で実行されるコードは、Go 1.2.1、Go 1.3、Go 1.4などと互換性があるはずですが、Go 1.1とは必ずしも互換性がありません。これは、Go 1.2で追加された機能のみを使用する可能性があるためです。
リリース間に追加され、ソースリポジトリで利用可能だが、番号付きバイナリリリースの一部ではない機能は、活発な開発中です。そのような機能を使用するソフトウェアについては、リリースされるまで互換性の約束はされません。
最後に、正確性の問題ではありませんが、プログラムのパフォーマンスが、依存するコンパイラまたはライブラリの実装の変更によって影響を受ける可能性があります。リリース間の特定のプログラムのパフォーマンスについては保証できません。
これらの期待はGo 1自体に適用されますが、Go 1に基づいた外部開発ソフトウェアの開発においても同様の考慮がなされることを願っています。
サブリポジトリ
メインのgoツリーのサブリポジトリ(例: golang.org/x/net)のコードは、より緩い互換性要件の下で開発される場合があります。ただし、サブリポジトリには、Go 1ポイントリリースと互換性のあるバージョンを識別するために、適切なタグが付けられます。
オペレーティングシステム
外部の当事者によって変更されるオペレーティングシステムインターフェースとの長期的な互換性を保証することは不可能です。したがって、`syscall`パッケージは、ここで提供される保証の範囲外です。Goバージョン1.4現在、`syscall`パッケージは凍結されています。システムコールインターフェースの進化は、`go.sys`サブリポジトリなど、他の場所でサポートされる必要があります。詳細と背景については、`このドキュメント`を参照してください。
ツール
最後に、Goツールチェーン(コンパイラ、リンカ、ビルドツールなど)は活発に開発されており、動作が変更される可能性があります。これは、たとえば、ツールの場所とプロパティに依存するスクリプトが、ポイントリリースによって壊れる可能性があることを意味します。
これらの注意点を除けば、Go 1はGoとそのエコシステムの発展のための確固たる基盤となると私たちは信じています。