Go 1 と Go プログラムの未来
はじめに
Go バージョン 1 (略して Go 1) のリリースは、この言語の開発における大きな節目です。Go 1 は、Go で書かれたプログラムやプロジェクトの成長のための安定したプラットフォームです。
Go 1 は、2 つのものを定義しています。1 つ目は、言語の仕様。2 つ目は、Go ライブラリの「標準パッケージ」であるコア API のセットの仕様です。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.2 でのみ追加された機能を使用する可能性があるため、必ずしも Go 1.1 と互換性があるとは限りません。
ソースリポジトリでは利用可能だが、番号付きのバイナリリリースの一部ではない、リリース間に追加された機能は、活発に開発中です。リリースされるまで、そのような機能を使用するソフトウェアの互換性は保証されません。
最後に、正確性の問題ではありませんが、プログラムのパフォーマンスは、依存するコンパイラまたはライブラリの実装の変更によって影響を受ける可能性があります。リリース間で特定のプログラムのパフォーマンスについて保証することはできません。
これらの期待は Go 1 自体に適用されますが、Go 1 に基づいて外部で開発されたソフトウェアの開発でも同様の考慮事項が考慮されることを願っています。
サブリポジトリ
golang.org/x/net などのメイン Go ツリーのサブリポジトリのコードは、より緩やかな互換性要件の下で開発される場合があります。ただし、サブリポジトリには、Go 1 のポイントリリースと互換性のあるバージョンを識別するために、適切にタグ付けされます。
オペレーティングシステム
外部の関係者によって変更されるオペレーティングシステムインターフェイスとの長期的な互換性を保証することは不可能です。したがって、syscall
パッケージは、ここで保証される範囲外です。Go バージョン 1.4 の時点で、syscall
パッケージはフリーズされています。システムコールインターフェイスの進化は、go.sys サブリポジトリなど、他の場所でサポートする必要があります。詳細と背景については、このドキュメントを参照してください。
ツール
最後に、Go ツールチェーン (コンパイラ、リンカー、ビルドツールなど) は活発に開発されており、動作が変更される可能性があります。これは、たとえば、ツールの場所とプロパティに依存するスクリプトが、ポイントリリースによって壊れる可能性があることを意味します。
これらの注意点は別として、Go 1 が Go とそのエコシステムの開発のための強固な基盤になると信じています。