Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 12438] ファイルの概要

このコミットは、Go言語の公式ドキュメントの一部である doc/go1compat.html ファイルに、Go 1の互換性に関する新しい注意書きを追加するものです。具体的には、Go言語における「ドットインポート(import .)」の使用に関する潜在的な問題と、将来のGoのリリースにおけるコンパイルエラーのリスクについて警告を追記しています。

コミット

doc: add note about import . to Go 1 compatibility notes

R=r
CC=golang-dev
https://golang.org/cl/5752065

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/25f15d5f22ef27a4452dd7924159e85d17f75648

元コミット内容

Go 1の互換性に関するドキュメントに、ドットインポート(import .)に関する注意書きを追加します。

変更の背景

Go言語では、パッケージをインポートする際に通常は import "path/to/package" のように記述し、パッケージ内の要素は package.Name のようにパッケージ名をプレフィックスとして参照します。しかし、import . "path/to/package" という形式(通称「ドットインポート」)を使用すると、インポートしたパッケージ内のエクスポートされた識別子を、パッケージ名をプレフィックスなしで直接参照できるようになります。

このコミットの背景には、ドットインポートがもたらす潜在的な名前衝突の問題があります。Go 1の互換性ガイドラインは、Go言語の将来のバージョンアップにおいても既存のコードが動作し続けることを保証するための重要な指針です。しかし、ドットインポートを使用している場合、インポート元のパッケージが将来のリリースで新しい識別子(関数、変数、型など)を追加すると、その新しい識別子が、ドットインポートを使用しているプログラム内の既存の識別子と名前衝突を起こす可能性があります。これにより、以前はコンパイルできていたコードが、Goの新しいバージョンではコンパイルエラーになるという互換性の問題が発生します。

この変更は、このような潜在的な互換性問題を開発者に警告し、ドットインポートの使用をテストコード以外では推奨しないというGoチームの立場を明確にするために行われました。これにより、開発者が将来のGoバージョンアップで予期せぬコンパイルエラーに遭遇するリスクを減らすことを目的としています。

前提知識の解説

Go言語のパッケージとインポート

Go言語は、コードをパッケージという単位で整理します。パッケージは関連する機能の集合であり、他のパッケージから利用することができます。他のパッケージの機能を利用するには、import キーワードを使ってそのパッケージをインポートする必要があります。

一般的なインポートの形式は以下の通りです。

import "fmt" // 標準ライブラリのfmtパッケージをインポート
import "myproject/mypackage" // 自身のプロジェクトのパッケージをインポート

インポートされたパッケージの識別子(関数、変数、型など)にアクセスするには、通常、パッケージ名.識別子 の形式を使用します。例えば、fmt パッケージの Println 関数を呼び出すには fmt.Println() と記述します。

ドットインポート (import .)

ドットインポートは、Go言語の特別なインポート形式の一つです。

import . "fmt"

この形式でインポートすると、インポートしたパッケージ(この例では fmt)のエクスポートされた識別子を、パッケージ名をプレフィックスなしで直接参照できるようになります。つまり、fmt.Println() ではなく Println() と記述できるようになります。

ドットインポートの主な用途:

  • テストコード: テストコードでは、テスト対象のパッケージの識別子を直接参照できるとコードが簡潔になるため、よく使用されます。
  • DSL (Domain Specific Language) の構築: 特定のドメインに特化した言語のような記述を可能にするために、意図的に使用されることがあります。

ドットインポートの欠点:

  • 名前衝突のリスク: 最も大きな問題は、名前衝突の可能性です。インポートしたパッケージが将来のバージョンで新しい識別子を追加した場合、それが現在のパッケージ内の識別子と名前衝突を起こし、コンパイルエラーになることがあります。
  • コードの可読性の低下: どの識別子がどのパッケージから来ているのかが不明瞭になり、コードの可読性が低下する可能性があります。特に、複数のドットインポートを使用している場合、混乱を招きやすくなります。
  • IDEの支援の低下: 一部のIDEやツールでは、ドットインポートされた識別子の補完や定義元へのジャンプがうまく機能しない場合があります。

Go 1 互換性保証

Go言語は、バージョン1.0以降、厳格な互換性保証を維持しています。これは、Go 1で書かれたプログラムは、Goの将来のバージョンでもコンパイルされ、動作し続けることを意味します。この互換性保証は、Goが安定したプラットフォームとして広く採用される上で非常に重要な要素です。

しかし、この互換性保証は、Go言語の仕様や標準ライブラリのAPIが変更されないことを意味するものではありません。非互換な変更は極力避けられますが、バグ修正やセキュリティパッチ、パフォーマンス改善などのために、ごく稀に非互換な変更が必要になることもあります。その場合、Goチームは互換性に関するドキュメント(go1compat.htmlなど)でその変更と影響について詳細に説明します。

ドットインポートは、このGo 1互換性保証の例外となりうるケースとして認識されており、今回のコミットはそのリスクを明示するために行われました。

技術的詳細

このコミットは、doc/go1compat.html というHTMLドキュメントに新しい <li> 要素を追加することで、ドットインポートに関する警告を組み込んでいます。

追加されたHTMLスニペットは以下の通りです。

<li>
Dot imports. If a program imports a standard package
using <code>import . "path"</code>, additional names defined in the
imported package in future releases may conflict with other names
defined in the program.  We do not recommend the use of <code>import .</code>
outside of tests, and using it may cause a program to fail
to compile in future releases.
</li>

このテキストは、ドットインポートが標準パッケージで使用された場合に、将来のリリースで追加される識別子と既存のプログラム内の識別子との間で名前衝突が発生する可能性を明確に述べています。そして、テスト以外の目的でのドットインポートの使用を推奨せず、その使用が将来のコンパイル失敗につながる可能性があることを警告しています。

これは技術的には、Goコンパイラが名前解決を行う際の挙動と関連しています。ドットインポートを使用すると、インポートされたパッケージのスコープが現在のパッケージのスコープに「フラット化」されます。これにより、コンパイラは、現在のパッケージ内で定義された識別子と、ドットインポートされたパッケージから来た識別子を区別なく扱います。もし両者に同じ名前の識別子が存在した場合、コンパイラはどちらを使用すべきか判断できず、名前衝突エラー(redeclared in this block など)を報告します。

Goチームは、標準ライブラリの進化に伴い、新しい関数、型、変数などを追加することがあります。これらの新しい識別子が、既存のユーザーコードでドットインポートによって取り込まれた際に、ユーザーコード内の識別子と偶然同じ名前になってしまう可能性はゼロではありません。このような事態を避けるため、Goチームはドットインポートの危険性を明示的に警告し、開発者にその使用を控えるよう促しています。

この警告は、Go 1互換性保証の原則を補完するものです。Go 1互換性は、Go言語の安定性と信頼性を高めるための基盤ですが、ドットインポートのような特定のコーディングパターンは、その保証の範囲外となるリスクをはらんでいることを示しています。

コアとなるコードの変更箇所

--- a/doc/go1compat.html
+++ b/doc/go1compat.html
@@ -94,6 +94,15 @@ We therefore recommend that composite literals whose type is defined
 in a separate package should use the tagged notation.
 </li>
 
+<li>
+Dot imports. If a program imports a standard package
+using <code>import . "path"</code>, additional names defined in the
+imported package in future releases may conflict with other names
+defined in the program.  We do not recommend the use of <code>import .</code>
+outside of tests, and using it may cause a program to fail
+to compile in future releases.\n+</li>
+\n </ul>
 
 <p>

コアとなるコードの解説

変更は doc/go1compat.html ファイルに対して行われています。これはGo言語の公式ドキュメントの一部であり、Go 1の互換性に関する重要な情報が記載されています。

追加されたコードは、HTMLのリストアイテム(<li>)として、既存のリストの途中に挿入されています。

  • <li> タグ: 新しいリスト項目を定義しています。
  • Dot imports.: ドットインポートに関する項目であることを示しています。
  • If a program imports a standard package using <code>import . "path"</code>, additional names defined in the imported package in future releases may conflict with other names defined in the program.:
    • 「もしプログラムが標準パッケージを import . "path" を使ってインポートしている場合」という条件を提示しています。
    • 「将来のリリースでインポートされたパッケージに定義される追加の名前が、プログラム内で定義された他の名前と衝突する可能性がある」という具体的なリスクを説明しています。
    • <code> タグで import . "path" を囲むことで、コードスニペットとして強調しています。
  • We do not recommend the use of <code>import .</code> outside of tests, and using it may cause a program to fail to compile in future releases.:
    • 「テスト以外の目的での import . の使用は推奨しない」というGoチームの公式な推奨事項を述べています。
    • 「その使用は将来のリリースでプログラムのコンパイルを失敗させる可能性がある」という結果を警告しています。

この追加により、Go 1互換性に関する公式ドキュメントが更新され、ドットインポートの潜在的な危険性について開発者への注意喚起が強化されました。これは、Go言語の安定性と長期的な保守性を維持するための重要なドキュメント更新です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント(Go 1 Compatibility Guaranteeに関する一般的な知識)
  • Go言語のパッケージとインポートに関する一般的な知識
  • Go言語のコンパイラの名前解決に関する一般的な知識