[インデックス 14974] ファイルの概要
このコミットは、Go言語の実験的なexp/locale/collate
パッケージにおける、Unicode文字列の照合(Collation)機能の再構築と、将来的な検索APIの追加に向けた準備を目的としています。主な変更点として、照合要素(collation element)の表現方法の変更(colElem
からElem
への型名変更)、照合と検索機能の分離、そして高レベルなオプションAPIの導入が挙げられます。これにより、コードのモジュール化と、ユーザーがより直感的に照合設定を行えるような改善が図られています。
コミット
commit f86ae990e859e026475380f0a1e0c86203d7a0d5
Author: Marcel van Lohuizen <mpvl@golang.org>
Date: Wed Jan 23 14:15:51 2013 +0100
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f86ae990e859e026475380f0a1e0c86203d7a0d5
元コミット内容
exp/locale/collate: preparation for adding Search API. Also changed the collate API
further to how (I believe) it will end up being.
It is nicer to separate search from sorting functionality. Collation needs tables that
are not needed by search and vice-versa. The common functionality is separated out
in the Weigher interface. As this interface is very low-level, it will be moved to
a sub package (colltab) in a next CL.
The types that will move to this package are Weigher, Elem, and Level. The addition
of Elem allows for removing some of the duplicate code between collate and collate/build.
This CL also introduces some stubs for a higher-level API for options. The default
proposed options are quite complex and require the user to have a decent understanding
of Unicode collation. The new options hide a lot of the complexity.
R=rsc
CC=golang-dev
https://golang.org/cl/7058051
変更の背景
このコミットの主な背景は、Go言語のexp/locale/collate
パッケージにおけるUnicode文字列の照合機能の改善と拡張です。具体的には以下の点が挙げられます。
- 検索APIの追加準備: 将来的に文字列の検索機能(Search API)を導入するにあたり、既存の照合APIの構造を見直す必要がありました。照合と検索は密接に関連していますが、それぞれが異なるデータ構造(テーブル)を必要とするため、機能を分離することでより効率的かつクリーンな設計を目指しています。
- APIの再設計: 既存の照合APIは、Unicode Collation Algorithm (UCA) の詳細な知識をユーザーに要求する部分がありました。これをより使いやすく、直感的な高レベルAPIにすることで、ユーザーがUnicode照合の複雑さに深く立ち入ることなく、適切な照合設定を行えるようにする意図があります。
- コードの重複排除とモジュール化:
collate
パッケージとcollate/build
パッケージ間で重複していたコードを削減し、共通の機能をWeigher
インターフェースとして分離することで、コードベースの保守性と再利用性を向上させています。特に、colElem
型をElem
型に統一することで、この重複排除が促進されました。 - 低レベル機能の分離:
Weigher
インターフェースのような低レベルな機能は、より専門的なサブパッケージ(colltab
)に移動される予定であり、これによりパッケージの役割分担が明確化されます。
これらの変更は、Go言語の国際化(i18n)サポートを強化し、より堅牢で使いやすい照合・検索機能を提供するための重要なステップです。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
Unicode Collation Algorithm (UCA)
UCAは、Unicode Technical Report #10 (UTR #10) で定義されている、Unicode文字列を言語的に正しい順序でソート(照合)するためのアルゴリズムです。単なるコードポイント順のソートでは、異なる言語や文化における文字の並び順の慣習を反映できません。UCAは、この複雑な要件を満たすために設計されています。
UCAの主要な概念は以下の通りです。
- 照合要素 (Collation Element: CE): 各文字や文字の組み合わせ(合字など)は、一つ以上の照合要素にマッピングされます。これらの照合要素が、実際の比較の単位となります。
- 多段階ソート (Multi-level Sorting): UCAは、複数のレベルで比較を行います。
- Primary Level (第一レベル): 文字の基本的な形状や識別子に基づきます。例えば、'a'と'b'の違い。
- Secondary Level (第二レベル): アクセント記号やダイアクリティカルマーク(分音記号)の違いに基づきます。例えば、'a'と'ä'の違い。
- Tertiary Level (第三レベル): 大文字・小文字の違いや、文字の幅(全角・半角)の違いに基づきます。例えば、'a'と'A'の違い。
- Quaternary Level (第四レベル): 可変要素(variable elements)の扱いに関連し、通常はPrimary Levelの値を再利用して、特定のルール(例: シフトされた重み付け)を適用します。これは、句読点や記号などの扱いを制御するために使用されます。
- ソートキー (Sort Key): UCAは、文字列を比較可能なバイト列(ソートキー)に変換します。このソートキーをバイナリ比較することで、UCAのルールに従った文字列の順序を決定できます。
LDML (Locale Data Markup Language)
LDMLは、Unicode Consortiumによって定義されたXMLベースのフォーマット(UTS#35)で、ロケールデータ(言語、地域、通貨、日付、時刻、数値の書式設定、照合ルールなど)を表現するための標準です。LDMLは、Unicode Common Locale Data Repository (CLDR) の基盤となっており、国際化されたソフトウェアの開発において、地域ごとの慣習やルールを統一的に扱うために不可欠です。
照合ルールもLDMLの一部として定義されており、特定の言語や地域における文字の並び順のカスタマイズを可能にします。
exp/locale/collate
パッケージの文脈
Go言語のexp
ディレクトリは、実験的なパッケージや将来的に標準ライブラリに取り込まれる可能性のあるパッケージを置く場所です。exp/locale/collate
は、Go言語におけるUnicode照合機能の初期実装または実験的なバージョンでした。このコミットが行われた2013年時点では、まだ開発途上にあり、その後のGo言語の進化に伴い、このパッケージの機能はgolang.org/x/text/collate
としてより成熟した形で提供されるようになりました。したがって、このコミットは、現在のgolang.org/x/text/collate
パッケージの基礎を築く重要なステップの一つと見なすことができます。
技術的詳細
このコミットは、exp/locale/collate
パッケージの内部構造にいくつかの重要な変更を加えています。
-
colElem
からElem
への型名変更と役割の明確化:- 以前は
colElem
という型が照合要素を表していましたが、このコミットでElem
に名称が変更されました。これは、より汎用的な「要素」としての役割を強調し、照合だけでなく検索など他の機能でも利用されることを示唆しています。 Elem
型には、Primary()
,Secondary()
,Tertiary()
,Quaternary()
,CCC()
(Canonical Combining Class),Mask()
などのメソッドが追加され、照合要素の各レベルの重みや特性をより明確に取得・操作できるようになりました。MakeElem
,MakeQuaternary
といったコンストラクタ関数も導入され、Elem
の生成がより構造化されています。
- 以前は
-
Weigher
インターフェースの導入:colltab.go
という新しいファイルが追加され、Weigher
インターフェースが定義されました。このインターフェースは、文字列から照合要素(Elem
)を生成する低レベルな機能(AppendNext
,AppendNextString
など)を抽象化します。- コミットメッセージにあるように、このインターフェースは「非常に低レベル」であり、将来的に
colltab
というサブパッケージに移動される予定です。これにより、照合テーブルの具体的な実装と、それを利用する高レベルな照合ロジックが分離されます。
-
Collator
構造体の変更とAPIの簡素化:Collator
構造体から、直接的な*table
フィールドが削除され、代わりにWeigher
インターフェース型のt
フィールドが導入されました。これにより、Collator
は具体的な照合テーブルの実装に依存せず、Weigher
インターフェースを介して照合要素を取得するようになります。Collator
のSetOptions
メソッドが導入され、Numeric
,IgnoreCase
,IgnoreDiacritics
などの高レベルなオプションをまとめて設定できるようになりました。これにより、ユーザーはUCAの複雑なレベル設定を直接操作することなく、一般的な照合要件を満たすことができます。Level
型(Primary
,Secondary
,Tertiary
,Quaternary
,Identity
)がcollate.go
からcolelem.go
に移動され、照合要素のレベルとより密接に関連付けられました。
-
内部処理の変更:
iter
構造体(文字列を走査して照合要素を生成するイテレータ)の内部も変更され、colElem
の代わりにElem
を使用するようになりました。また、setInput
やsetInputString
メソッドから*Collator
引数が削除され、より独立した動作が可能になっています。table.go
内のappendNext
関数もElem
型を扱うように変更され、source
構造体も導入されて文字列とバイト列の処理を抽象化しています。
これらの変更は、Go言語の照合パッケージが、よりモジュール化され、拡張性があり、かつユーザーフレンドリーなAPIを提供する方向へと進化していることを示しています。特に、低レベルな照合要素の処理と高レベルな照合ロジックの分離は、今後の機能追加(特に検索API)やパフォーマンス最適化において重要な基盤となります。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下のファイルに集中しています。
-
src/pkg/exp/locale/collate/colelem.go
:colElem
型がElem
型にリネームされました。Level
型がcollate.go
からこのファイルに移動されました。Elem
型にPrimary()
,Secondary()
,Tertiary()
,Quaternary()
,CCC()
,Mask()
,Weight()
などのメソッドが追加されました。MakeElem
,MakeQuaternary
といった新しいコンストラクタ関数が追加されました。- 定数
maxQuaternary
がMaxQuaternary
にリネームされました。
-
src/pkg/exp/locale/collate/collate.go
:Level
型の定義が削除され、colelem.go
に移動されました。Collator
構造体のt *table
フィールドがt Weigher
インターフェース型に変更されました。SetOptions
メソッドとOption
型が追加され、高レベルな照合オプションを設定できるようになりました。NewFromTable
関数が追加され、Weigher
インターフェースを受け取るようになりました。Collator
のiter
フィールドの型がcolElem
からElem
に変更されました。keyFromElems
関数が[]colElem
の代わりに[]Elem
を受け取るようになりました。processWeights
関数も[]colElem
の代わりに[]Elem
を受け取るようになりました。
-
src/pkg/exp/locale/collate/colltab.go
(新規ファイル):Weigher
インターフェースが定義されました。このインターフェースは、照合要素の生成に関する低レベルな操作を抽象化します。
-
src/pkg/exp/locale/collate/table.go
:table
構造体がWeigher
インターフェースを実装するようになりました。AppendNext
,AppendNextString
,Start
,StartString
,Domain
といったWeigher
インターフェースのメソッドが追加されました。- 内部の
appendNext
,appendExpansion
,matchContraction
,matchContractionString
関数がcolElem
の代わりにElem
を扱うように変更されました。 source
構造体が定義され、文字列とバイト列の処理を抽象化しました。
-
src/pkg/exp/locale/collate/trie.go
:lookupValue
,lookup
,lookupString
関数がcolElem
の代わりにElem
を返すように変更されました。
-
src/pkg/exp/locale/collate/colelem_test.go
:- テストコード内の
colElem
型がElem
型に更新されました。
- テストコード内の
コアとなるコードの解説
Elem
型への変更と照合要素の操作
最も根本的な変更は、照合要素を表す型がcolElem
からElem
にリネームされたことです。これは単なる名称変更以上の意味を持ちます。Elem
型には、Unicode Collation Algorithm (UCA) の各レベル(Primary, Secondary, Tertiary, Quaternary)に対応する重みを取得するためのメソッド(Primary()
, Secondary()
, Tertiary()
, Quaternary()
)が追加されました。これにより、照合要素の内部表現を直接操作することなく、よりセマンティックな方法で各レベルの重みにアクセスできるようになります。
例えば、以前はce.primary()
のように直接フィールドにアクセスしていた箇所が、ce.Primary()
というメソッド呼び出しに変わっています。これは、オブジェクト指向的なアプローチを強化し、将来的な内部実装の変更に対する柔軟性を提供します。
また、MakeElem
やMakeQuaternary
といったファクトリ関数が導入されたことで、Elem
オブジェクトの生成がより安全かつ意図的に行えるようになりました。
Weigher
インターフェースによる機能分離
colltab.go
で定義されたWeigher
インターフェースは、このコミットの設計思想の中心です。このインターフェースは、入力文字列から照合要素のシーケンスを生成する低レベルなロジックを抽象化します。
type Weigher interface {
Start(p int, b []byte) int
StartString(p int, s string) int
AppendNext(buf []Elem, s []byte) (ce []Elem, n int)
AppendNextString(buf []Elem, s string) (ce []Elem, n int)
Domain() []string
}
Collator
構造体は、具体的な照合テーブルの実装(*table
)を直接持つ代わりに、このWeigher
インターフェースを実装するオブジェクトを持つようになりました。これにより、Collator
は「どのように照合要素が生成されるか」という詳細から切り離され、「生成された照合要素をどのように比較するか」という高レベルなロジックに集中できるようになります。
この分離は、将来的に異なる照合テーブルの実装(例: 特定の言語に特化したテーブル、よりコンパクトなテーブルなど)を容易にプラグインできるようにするための重要なステップです。また、コミットメッセージにあるように、照合と検索で共通する低レベルな機能がWeigher
として抽出されたことで、コードの再利用性が向上し、それぞれの機能が独立して進化できるようになります。
Collator.SetOptions
による高レベルAPIの提供
Collator
構造体に追加されたSetOptions
メソッドとOption
型は、ユーザーエクスペリエンスの向上を目的としています。
type Option int
const (
Numeric Option = 1 << iota // Sort numbers numerically ("2" < "12").
IgnoreCase // Case-insensitive search.
IgnoreDiacritics // Ignore diacritical marks. ("o" == "ö").
IgnoreWidth // Ignore full versus normal width.
UpperFirst // Sort upper case before lower case.
LowerFirst // Sort lower case before upper case.
Force // Force ordering if strings are equivalent but not equal.
Loose = IgnoreDiacritics | IgnoreWidth | IgnoreCase
)
func (c *Collator) SetOptions(o Option) {
// TODO: implement
}
以前のAPIでは、ユーザーがUCAのPrimary, Secondary, Tertiaryといったレベルを直接操作して照合の挙動を制御する必要がありました。これは強力ですが、Unicode照合の専門知識がないユーザーにとっては複雑でした。SetOptions
は、Numeric
(数値ソート)、IgnoreCase
(大文字・小文字を無視)、IgnoreDiacritics
(アクセント記号を無視)といった、より直感的で一般的な照合オプションを提供します。
これにより、ユーザーは「大文字・小文字を区別しないソート」や「アクセント記号を無視したソート」といった具体的な要件を、UCAの内部的なレベル構造を意識することなく設定できるようになります。これは、APIの使いやすさを大幅に向上させる変更です。
これらの変更は全体として、exp/locale/collate
パッケージが、より堅牢で、モジュール化され、かつユーザーフレンドリーな国際化機能を提供するための基盤を築いていることを示しています。