[インデックス 15208] ファイルの概要
コミット
このコミット f38da96755cea4fde703b4601d5959150587eab4 は、Go言語の実験的なロケールパッケージ exp/locale/collate における低レベルの照合(collation)機能を、colltab という独立したパッケージに移動させるものです。これにより、照合機能が search パッケージなど他のパッケージと共有される際に、それぞれのパッケージが同じテーブルを使用する必要がなくなり、モジュール間の結合度が低減されます。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f38da96755cea4fde703b4601d5959150587eab4
元コミット内容
exp/locale/collate: moved low-level collation functionality
into separate package. This allows this code to be shared
with the search package without the need for these two to use
the same tables.
Adjusted various files accordingly.
R=rsc
CC=golang-dev
https://golang.org/cl/7213044
変更の背景
この変更の主な背景は、Go言語の実験的なロケールパッケージ exp/locale/collate が提供する低レベルの照合機能を、より広範な用途で再利用可能にすることです。具体的には、search パッケージのような他のパッケージが照合機能を利用する際に、collate パッケージが内部的に使用するデータテーブルに依存することなく、独立して機能を利用できるようにすることが目的です。
従来の設計では、collate パッケージ内の低レベル機能とデータテーブルが密接に結合しており、これが他のパッケージでの再利用を妨げていました。この結合を解消することで、collate パッケージは高レベルの照合ロジックに集中し、低レベルのデータ構造やアルゴリズムは colltab パッケージが担当するという、よりクリーンなアーキテクチャが実現されます。これにより、将来的に異なる照合テーブルやアルゴリズムを導入する際の柔軟性も向上します。
前提知識の解説
照合(Collation)
照合とは、文字列を特定の順序で並べ替える(ソートする)プロセスです。これは単なる文字コードの比較ではなく、言語や文化に特有のルール(例: アクセント記号の有無、大文字・小文字の区別、特定の文字の並び順など)に基づいて行われます。例えば、ドイツ語では 'ä' は 'a' の後に来ることがありますが、スウェーデン語では 'z' の後に来ることがあります。
Unicode Collation Algorithm (UCA)
Unicode Collation Algorithm (UCA) は、Unicode Consortiumによって定義された、多言語対応の照合のための標準アルゴリズムです。UCAは、文字列を比較するために「照合要素(Collation Elements)」と呼ばれる数値のシーケンスに変換します。これらの照合要素は、通常、プライマリ、セカンダリ、ターシャリ、クォータナリの4つのレベルの重み(weights)を持ちます。
- プライマリ(Primary): 文字の基本的な形状に基づいた重み。例えば、'a' と 'A' は同じプライマリ重みを持ちます。
- セカンダリ(Secondary): アクセント記号やダイアクリティカルマークに基づいた重み。例えば、'a' と 'á' は異なるセカンダリ重みを持ちます。
- ターシャリ(Tertiary): 大文字・小文字の区別や、半角・全角などのバリアントに基づいた重み。例えば、'a' と 'A' は異なるターシャリ重みを持ちます。
- クォータナリ(Quaternary): 可変要素(variable elements)の処理に使用される重み。句読点や記号など、通常は無視される文字の順序を決定するために使用されます。
Go言語の exp パッケージ
Go言語の標準ライブラリには、exp というプレフィックスを持つパッケージが存在します。これらは「実験的(experimental)」なパッケージであり、まだ安定版としてリリースされていない機能やAPIが含まれています。これらのパッケージは、将来的に標準ライブラリに組み込まれる可能性がありますが、APIが変更されたり、削除されたりする可能性もあります。
Go言語のパッケージ構造とインポート
Go言語では、コードはパッケージに分割されます。パッケージはディレクトリ構造に対応し、他のパッケージの関数や型を使用するには import ステートメントで明示的にインポートする必要があります。例えば、exp/locale/collate パッケージ内の型や関数を使用するには import "exp/locale/collate" と記述します。このコミットでは、exp/locale/collate パッケージが exp/locale/collate/colltab パッケージに依存するように変更されています。
技術的詳細
このコミットの技術的な核心は、Go言語のパッケージ分割と依存関係の再構築にあります。
-
新パッケージ
colltabの導入:src/pkg/exp/locale/collate/ディレクトリ内に存在していた、照合の低レベルなデータ構造やアルゴリズム(例: 照合要素の表現、Trie構造、テーブルの初期化など)を扱うファイル群が、新たに作成されたsrc/pkg/exp/locale/collate/colltab/ディレクトリに移動されました。これにより、colltabは照合テーブルの内部表現と、それらを操作するための基本的な機能を提供する独立したパッケージとなります。 -
ファイルのリネームと移動: 以下のファイルが
collateパッケージからcolltabパッケージへ移動し、パッケージ名がcollateからcolltabに変更されました。colelem.gocolelem_test.gocolltab.go(このファイル自体がcolltabパッケージのインターフェースを定義する中心的なファイルとなる)contract.gocontract_test.goexport.gotable.gotrie.gotrie_test.go
-
インポートパスの更新:
collateパッケージ内のファイルや、collateパッケージに依存していた他のファイル(例:buildパッケージ内のファイル、collate_test.goなど)では、移動された機能や型を参照するためにインポートパスがexp/locale/collateからexp/locale/collate/colltabへと変更されました。例えば、collate.Levelやcollate.Elemといった型は、colltab.Levelやcolltab.Elemとして参照されるようになります。 -
collate.Collatorの変更:collate.Collator構造体は、直接colltab.Weigherインターフェースを実装する型(colltab.tableなど)を参照するように変更されました。これにより、Collatorは低レベルの実装詳細から切り離され、colltabパッケージが提供する抽象化されたインターフェースを通じて照合データにアクセスするようになります。 -
MakeElem関数の移動と利用: 照合要素(Collation Element)を作成するmakeCE関数(build/colelem.goにあった)のロジックが、colltab/colelem.go内のMakeElem関数として再実装されました。これにより、照合要素の生成ロジックが低レベルパッケージに集約され、buildパッケージからはcolltab.MakeElemを呼び出す形に変更されました。 -
index.goの新規追加:src/pkg/exp/locale/collate/index.goが新規追加されました。このファイルは、照合テーブルのインデックス情報(tableIndex構造体)を定義し、colltabパッケージが提供する低レベルのデータにアクセスするための橋渡しをします。
この変更により、collate パッケージは高レベルの照合APIとロジックを提供し、colltab パッケージは照合データの内部表現と基本的な操作に特化するという、明確な役割分担が実現されました。これにより、colltab パッケージは collate パッケージだけでなく、search パッケージなど他のGoパッケージからも独立して利用できるようになり、コードの再利用性と保守性が向上します。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、主に以下の2点に集約されます。
-
インポートパスの変更:
src/pkg/exp/locale/collate/build/builder.goの例を見ると、import "exp/locale/collate"がimport "exp/locale/collate/colltab"に変更されています。--- a/src/pkg/exp/locale/collate/build/builder.go +++ b/src/pkg/exp/locale/collate/build/builder.go @@ -5,7 +5,7 @@ package build import ( -" exp/locale/collate" +" exp/locale/collate/colltab" "exp/norm" "fmt" "io" -
型参照の変更: 上記インポートパスの変更に伴い、
collateパッケージで定義されていた型(例:collate.Level)が、新しく移動されたcolltabパッケージの型(例:colltab.Level)に置き換えられています。src/pkg/exp/locale/collate/build/builder.goのInsertメソッドのシグネチャの変更がその一例です。--- a/src/pkg/exp/locale/collate/build/builder.go +++ b/src/pkg/exp/locale/collate/build/builder.go @@ -225,25 +225,25 @@ func (t *Tailoring) SetAnchorBefore(anchor string) error { // at the primary sorting level: // t := b.Tailoring("se") // \t\tt.SetAnchor("z") -// \t\tt.Insert(collate.Primary, "ä", "") +// \t\tt.Insert(colltab.Primary, "ä", "") // Order "ü" after "ue" at the secondary sorting level: //\t\tt.SetAnchor("ue") -//\t\tt.Insert(collate.Secondary, "ü","") +//\t\tt.Insert(colltab.Secondary, "ü","") // or //\t\tt.SetAnchor("u") -//\t\tt.Insert(collate.Secondary, "ü", "e") +//\t\tt.Insert(colltab.Secondary, "ü", "e") // Order "q" afer "ab" at the secondary level and "Q" after "q" // at the tertiary level: // \t\tt.SetAnchor("ab") -// \t\tt.Insert(collate.Secondary, "q", "") -// \t\tt.Insert(collate.Tertiary, "Q", "") +// \t\tt.Insert(colltab.Secondary, "q", "") +// \t\tt.Insert(colltab.Tertiary, "Q", "") // Order "b" before "a": // t.SetAnchorBefore("a") -// t.Insert(collate.Primary, "b", "") +// t.Insert(colltab.Primary, "b", "") // Order "0" after the last primary ignorable: // t.SetAnchor("<last_primary_ignorable/>") -// t.Insert(collate.Primary, "0", "") -+func (t *Tailoring) Insert(level collate.Level, str, extend string) error { ++func (t *Tailoring) Insert(level colltab.Level, str, extend string) error { if t.anchor == nil { return fmt.Errorf("%s:Insert: no anchor point set for tailoring of %s", t.id, str) }同様に、
src/pkg/exp/locale/collate/collate.goでは、Collator構造体のStrengthフィールドの型がLevelからcolltab.Levelに変更されています。--- a/src/pkg/exp/locale/collate/collate.go +++ b/src/pkg/exp/locale/collate/collate.go @@ -46,7 +47,7 @@ type Collator struct { // diacritical marks to be ignored but not case without having to fiddle with levels). // Strength sets the maximum level to use in comparison. - Strength Level + Strength colltab.Level // Alternate specifies an alternative handling of variables. Alternate AlternateHandling
コアとなるコードの解説
このコミットの主要な目的は、照合機能の低レベルな部分を colltab という新しいパッケージに分離し、exp/locale/collate パッケージがその高レベルなインターフェースとして機能するようにすることです。
上記のコード変更箇所は、この分離がどのように行われたかを示しています。
-
import "exp/locale/collate/colltab": これは、exp/locale/collateパッケージ内のファイルが、新しく作成されたcolltabパッケージの機能を利用するために必要な変更です。Go言語では、他のパッケージの公開された(エクスポートされた)識別子(関数、変数、型など)を使用するには、そのパッケージをインポートする必要があります。この変更により、collateパッケージはcolltabパッケージに依存するようになります。 -
collate.Levelからcolltab.Levelへの変更:Level型は、照合の比較レベル(プライマリ、セカンダリ、ターシャリなど)を定義する列挙型です。この型がcolltabパッケージに移動されたため、collateパッケージやその関連パッケージ(buildなど)でLevelを参照する際には、colltab.Levelという完全修飾名を使用する必要があります。これは、Go言語におけるパッケージ間の依存関係と、識別子のスコープの基本的なルールに従った変更です。例えば、
Tailoring構造体のInsertメソッドのシグネチャがfunc (t *Tailoring) Insert(level collate.Level, str, extend string) errorからfunc (t *Tailoring) Insert(level colltab.Level, str, extend string) errorに変更されたのは、Level型がcolltabパッケージに移動したためです。同様に、collate.Primaryやcollate.Secondaryといった定数も、colltab.Primaryやcolltab.Secondaryに変更されています。
これらの変更は、照合ロジックの低レベルな実装詳細を colltab パッケージにカプセル化し、collate パッケージはより高レベルな照合APIを提供するという、明確な責任分担を確立します。これにより、collate パッケージのコードはより簡潔になり、colltab パッケージは他のGoパッケージからも独立して再利用可能なコンポーネントとして機能できるようになります。これは、Go言語における良いパッケージ設計の原則(単一責任の原則、疎結合など)に沿った改善と言えます。
関連リンク
- Go Collation Algorithm (UCA) のドキュメント: https://pkg.go.dev/golang.org/x/text/collate (これは
expパッケージが安定版になった後のものですが、概念は共通です) - Unicode Collation Algorithm (UCA) の公式ドキュメント: http://www.unicode.org/reports/tr10/
参考にした情報源リンク
- コミットメッセージ:
exp/locale/collate: moved low-level collation functionality into separate package. - Go言語のパッケージとモジュールの概念に関する公式ドキュメント (一般的な情報源として): https://go.dev/doc/modules/
- Go言語の
expパッケージに関する一般的な情報 (Goコミュニティの慣習として): https://go.dev/doc/go1.11#modules (Go Modulesの導入に関するドキュメントですが、expパッケージの性質についても触れられています) - Unicode Collation Algorithm (UCA) の概念に関する一般的な情報源 (Wikipediaなど): https://ja.wikipedia.org/wiki/Unicode%E7%85%A7%E5%90%88%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0