[インデックス 13561] ファイルの概要
このコミットは、Go言語の実験的なexp/locale/collate
パッケージにおけるBuilder
APIの変更に関するものです。特に、CLDR (Common Locale Data Repository) ファイルの処理をより便利にするための改善が施されています。
コミット
commit 89d40b911c0e1f7012e2f463919d8093a49797cc
Author: Marcel van Lohuizen <mpvl@golang.org>
Date: Fri Aug 3 09:01:21 2012 +0200
exp/locale/collate: changed API of Builder to be more convenient
for dealing with CLDR files:
- Add now taxes a list of indexes of colelems that are variables. Checking and
handling is now done by the Builder. VariableTop is now also properly generated
using the Build method.
- Introduced separate Builder, called Tailoring, for creating tailorings of root
table. This clearly separates the functionality for building a table based on
weights (the allkeys* files) versus tables based on LDML XML files.
- Tailorings are now added by two calls instead of one: SetAnchor and Insert.
This more closely reflects the structure of LDML side and simplifies the
implementation of both the client and library side. It also preserves
some information that is otherwise hard to recover for the Builder.
- Allow the LDML XML element extend to be passed to Insert. This simplifies
both client and library implementation.
R=r
CC=golang-dev
https://golang.org/cl/6454061
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/89d40b911c0e1f7012e2f463919d8093a49797cc
元コミット内容
上記の「コミット」セクションに記載されている内容が元コミット内容です。
変更の背景
このコミットの背景には、Go言語のexp/locale/collate
パッケージが、Unicode Collation Algorithm (UCA) および Common Locale Data Repository (CLDR) のデータに基づいて、文字列の照合(ソート)ルールを構築する際の利便性と正確性を向上させるという目的があります。
従来のBuilder
APIは、CLDRの複雑なデータ構造、特に「テーラリング(Tailoring)」と呼ばれるロケール固有の照合ルールのカスタマイズを効率的に扱うには不十分でした。CLDRは、各言語や地域に特有のソート順序を定義するためにLDML (Locale Data Markup Language) というXML形式を使用しており、その中には「可変要素(Variable Collation Elements)」や「拡張(Extend)」といった概念が含まれます。
このコミットは、以下の課題を解決するために行われました。
- 可変要素の適切な処理: UCAでは、句読点や記号などの一部の文字を「可変要素」として扱い、照合の強度(Primary, Secondary, Tertiaryなど)に応じてその重みを無視したり、異なる方法で処理したりします。
VariableTop
という概念は、可変要素のプライマリ重みの上限を定義します。以前のAPIでは、この可変要素のチェックとVariableTop
の生成が十分に自動化されていませんでした。 - テーラリング構築の複雑性: ルートの照合テーブル(UCAのデフォルトルール)に加えて、特定のロケール(例: ドイツ語、スウェーデン語)に合わせたテーラリングを構築するプロセスが、APIレベルで明確に分離されておらず、実装が複雑でした。特に、LDML XMLファイルで定義されるテーラリングは、重みファイル(
allkeys*
)から構築される基本テーブルとは異なるアプローチを必要とします。 - LDML構造との乖離: LDMLのテーラリングは、特定のアンカー(基準点)に対して要素を挿入するという構造を持っています。以前のAPIでは、これを単一の
AddTailoring
呼び出しで処理しようとしており、LDMLのセマンティクスを直接反映していませんでした。これにより、クライアント側とライブラリ側の両方で実装が複雑になり、一部の情報が失われる可能性がありました。 - LDML
extend
要素のサポート: LDMLには、特定の文字の照合要素に別の文字の照合要素を「拡張」するextend
要素が存在します。これをAPIで直接サポートすることで、テーラリングの定義がより直感的になります。
これらの課題に対処するため、Builder
APIの再設計が行われ、Tailoring
という新しい概念の導入、テーラリング追加のためのSetAnchor
とInsert
の分離、そしてAdd
メソッドでの可変要素の明示的な指定が導入されました。これにより、CLDRデータからの照合テーブル構築がより堅牢で、かつ開発者にとって扱いやすくなることを目指しています。
前提知識の解説
このコミットの変更内容を理解するためには、以下の概念について理解しておく必要があります。
1. 文字コードとUnicode
- 文字コード: コンピュータが文字を扱うための符号化方式。
- Unicode: 世界中のあらゆる文字を統一的に扱うための文字コード標準。
2. 文字列の照合(Collation)
文字列の照合とは、文字列を特定の順序で並べ替える(ソートする)プロセスです。単純なバイナリ比較ではなく、言語や文化に特有のルールに基づいて行われます。例えば、英語では大文字と小文字を区別しないソート、ドイツ語ではウムラウト文字の扱い、スウェーデン語では特定の文字がアルファベットの最後にくる、といったルールがあります。
3. Unicode Collation Algorithm (UCA)
UCAは、Unicode Consortiumによって定義された、多言語対応の文字列照合のための標準アルゴリズムです。UCAは、各文字に「照合要素(Collation Element: CE)」と呼ばれる数値の重みを割り当てることで、言語に依存しない一貫したソート順序を提供します。
- 照合要素(CE): 各文字または文字シーケンスに割り当てられる重み。通常、プライマリ(Primary)、セカンダリ(Secondary)、ターシャリ(Tertiary)の3つのレベルの重みで構成されます。
- プライマリ重み: 文字の基本的な形状やアルファベット順を決定します。例えば、'a'と'b'は異なるプライマリ重みを持ちます。
- セカンダリ重み: アクセント記号やダイアクリティカルマーク(例: 'a'と'ä')の違いを区別します。
- ターシャリ重み: 大文字と小文字、または幅の違い(全角/半角)を区別します。
- クォータナリ重み: 可変要素の処理に使用されることがあります。
4. Common Locale Data Repository (CLDR)
CLDRは、Unicode Consortiumが提供する、ロケール(言語と地域)に関するデータのリポジトリです。日付、時刻、通貨の書式、数値の書式、言語名、国名、そして照合ルールなど、国際化(i18n)と地域化(l10n)に必要な情報が網羅されています。CLDRの照合ルールはUCAに基づいていますが、特定のロケールに合わせたカスタマイズ(テーラリング)が施されています。
5. Locale Data Markup Language (LDML)
LDMLは、CLDRのデータを表現するためのXMLベースのマークアップ言語です。CLDRの照合ルールもLDML形式で記述されており、特定の文字の重みの変更や、文字の挿入、削除、拡張などのテーラリングが定義されます。
6. テーラリング(Tailoring)
テーラリングとは、UCAのデフォルトの照合ルールを、特定の言語や地域の慣習に合わせてカスタマイズすることです。例えば、ドイツ語では'ä'が'a'と'b'の間にソートされるのではなく、'a'の後にソートされるといったルールがあります。LDMLでは、<collation>
要素内に<rule>
要素などを用いてテーラリングが記述されます。
- アンカー(Anchor): テーラリングにおいて、新しい照合要素を挿入する際の基準となる既存の要素。LDMLでは、
<reset>
要素で指定されます。例えば、<reset value="z"/>
は「'z'の後に挿入する」ことを意味します。 - 可変要素(Variable Collation Elements): UCAでは、句読点、記号、スペースなどの一部の文字を「可変要素」として扱います。これらの要素は、照合の強度(Strength)設定に応じて、プライマリレベルでの比較時に無視されたり、特別な重みが割り当てられたりします。
VariableTop
は、可変要素のプライマリ重みの上限を定義する値です。この値より小さいプライマリ重みを持つ要素は可変要素と見なされます。 - 拡張(Extend): LDMLのテーラリングにおいて、ある文字の照合要素に別の文字の照合要素を「拡張」して追加する概念です。例えば、
<a><extend>b</extend></a>
は、'a'の照合要素に'b'の照合要素を追加することを意味し、結果として「ab」としてソートされるような効果をもたらします。
7. Go言語のexp/locale/collate
パッケージ
このパッケージは、Go言語でUCAとCLDRに基づいた文字列照合機能を提供する実験的なライブラリです。Builder
は照合テーブルを構築するための主要な構造体であり、このコミットでそのAPIが大幅に改善されました。
技術的詳細
このコミットは、exp/locale/collate
パッケージの内部構造とAPIにいくつかの重要な変更を加えています。
1. Builder
とTailoring
の役割分担
Builder
: 以前はルートテーブルとテーラリングの両方を扱っていましたが、この変更により、Builder
はルート照合テーブルの構築に特化しました。これは主にUCAのallkeys*
ファイル(文字と照合要素の重みのマッピング)からデータを読み込み、基本となる照合テーブルを生成する役割を担います。Tailoring
: 新たに導入された構造体で、既存の照合テーブル(通常はルートテーブル)に対するロケール固有のテーラリングを構築する役割を担います。これはCLDRのLDML XMLファイルで定義されるカスタマイズを反映するためのものです。これにより、重みベースのテーブル構築とLDMLベースのテーラリング構築の機能が明確に分離され、コードのモジュール性と理解しやすさが向上しました。
2. Builder.Add
メソッドの変更
Add(str []rune, colelems [][]int, variables []int)
: 以前はvariables
引数がありませんでしたが、この変更で追加されました。str
: 照合要素を割り当てるルーン(文字)のスライス。colelems
:str
に対応する照合要素のシーケンス。各要素はプライマリ、セカンダリ、ターシャリなどの重みのスライスです。variables
:colelems
内のどの照合要素が「可変要素」であるかを示すインデックスのリスト。
- 可変要素の自動処理:
Builder.Add
メソッド内で、variables
引数に基づいて可変要素のチェックと処理が自動的に行われるようになりました。具体的には、minNonVar
(最小の非可変要素のプライマリ重み)とvarTop
(最大の可変要素のプライマリ重み)がBuilder
内部で追跡され、整合性チェックが行われます。これにより、VariableTop
の値がBuild
メソッドによって適切に生成されるようになりました。
3. テーラリング追加APIの変更 (SetAnchor
とInsert
の導入)
Tailoring.SetAnchor(anchor string)
: テーラリングにおいて、新しい要素を挿入する基準となる「アンカー」を設定します。これはLDMLの<reset>
要素に相当します。例えば、SetAnchor("z")
は「'z'の後に挿入する」ことを意味します。特殊なアンカー(例:<first_tertiary_ignorable/>
)もサポートされる予定です。Tailoring.SetAnchorBefore(anchor string)
:SetAnchor
と同様ですが、アンカーの「前に」要素を挿入します。Tailoring.Insert(level collate.Level, str, extend string)
:SetAnchor
で設定されたアンカーに対して、新しい照合要素を挿入します。level
: 挿入する照合のレベル(Primary, Secondary, Tertiaryなど)。str
: 挿入する文字列。extend
: LDMLのextend
要素に対応する文字列。これが非空の場合、str
の照合要素にextend
の照合要素が追加されます。これにより、anchor + extend
の後にstr
がソートされるのと同等の効果が得られます。
- LDML構造の反映: 以前の単一の
AddTailoring
呼び出しから、SetAnchor
とInsert
の2段階の呼び出しに分離されたことで、LDMLのテーラリング定義(アンカーを設定し、その後に要素を挿入する)がより直接的にAPIに反映されるようになりました。これにより、クライアントコードの記述がLDMLのセマンティクスに近づき、ライブラリ内部の実装も簡素化されました。
4. Collator
とtable
構造体の変更
collate.Collator
構造体からvariableTop
フィールドが削除され、代わりにcollate.table
構造体(照合テーブルの内部表現)にvariableTop
が移動しました。これにより、Collator
インスタンスが参照するテーブルデータの一部としてvariableTop
が管理されるようになり、データの一貫性が向上しました。collate.Init
関数(Builder
がCollator
インスタンスを生成する際に使用)も、新しいtableInitializer
インターフェースを通じてvariableTop
を取得するように変更されました。
5. maketables.go
の変更
parseUCA
関数がBuilder.Add
を呼び出す際に、可変要素のインデックスリストを渡すように変更されました。これにより、可変要素の検出とVariableTop
の計算がBuilder
内部で行われるようになりました。failonerror
関数がfailOnError
にリネームされ、Goの慣習に合わせた命名になりました。
これらの変更により、exp/locale/collate
パッケージは、CLDRの複雑な照合データ、特にテーラリングと可変要素の処理を、より正確かつ効率的に行えるようになりました。
コアとなるコードの変更箇所
主要な変更は以下のファイルに集中しています。
src/pkg/exp/locale/collate/build/builder.go
:Builder
構造体とAdd
メソッドの変更、Tailoring
構造体とSetAnchor
,Insert
メソッドの追加。src/pkg/exp/locale/collate/build/table.go
:table
構造体にvariableTop
フィールドの追加。src/pkg/exp/locale/collate/collate.go
:Collator
構造体からvariableTop
フィールドの削除と、t.variableTop
への参照変更。src/pkg/exp/locale/collate/export.go
:Init
関数でのvariableTop
の取得方法の変更。src/pkg/exp/locale/collate/maketables.go
:parseUCA
関数でのBuilder.Add
呼び出しの変更と、Builder.Build
の引数変更。
src/pkg/exp/locale/collate/build/builder.go
--- a/src/pkg/exp/locale/collate/build/builder.go
+++ b/src/pkg/exp/locale/collate/build/builder.go
@@ -60,18 +65,30 @@ func (e *entry) contractionStarter() bool {
return e.contractionHandle.n != 0
}
-// A Builder builds collation tables. It can generate both the root table and
-// locale-specific tables defined as tailorings to the root table.\n// The typical use case is to specify the data for the root table and all locale-specific\n// tables using Add and AddTailoring before making any call to Build. This allows\n// Builder to ensure that a root table can support tailorings for each locale.\n+type Builder struct {
+ index *trieBuilder
+ locale []*Tailoring
+ entryMap map[string]*entry
+ entry []*entry
+ t *table
+ err error
+ built bool
+
+ minNonVar int // lowest primary recorded for a variable
+ varTop int // highest primary recorded for a non-variable
+}
+
+// A Tailoring builds a collation table based on another collation table.
+// The table is defined by specifying tailorings to the underlying table.
+// See http://unicode.org/reports/tr35/ for an overview of tailoring
+// collation tables. The CLDR contains pre-defined tailorings for a variety
+// of languages (See http://www.unicode.org/Public/cldr/2.0.1/core.zip.)
+type Tailoring struct {
+ id string
+ // TODO: implement.
+}
+
// NewBuilder returns a new Builder.
@@ -83,14 +100,26 @@ func NewBuilder() *Builder {
return b
}
-// Add adds an entry for the root collation element table, mapping \n+// Tailoring returns a Tailoring for the given locale. One should \n+// have completed all calls to Add before calling Tailoring.\n+func (b *Builder) Tailoring(locale string) *Tailoring {
+ t := &Tailoring{
+ id: locale,
+ }
+ b.locale = append(b.locale, t)
+ return t
+}
+
+// Add adds an entry to the collation element table, mapping \n // a slice of runes to a sequence of collation elements.\n // A collation element is specified as list of weights: []int{primary, secondary, ...}.\n // The entries are typically obtained from a collation element table\n // as defined in http://www.unicode.org/reports/tr10/#Data_Table_Format.\n // Note that the collation elements specified by colelems are only used\n // as a guide. The actual weights generated by Builder may differ.\n-func (b *Builder) Add(str []rune, colelems [][]int) error {\n+// The argument variables is a list of indices into colelems that should contain\n+// a value for each colelem that is a variable. (See the reference above.)\n+func (b *Builder) Add(str []rune, colelems [][]int, variables []int) error {
e := &entry{
runes: make([]rune, len(str)),
elems: make([][]int, len(colelems)),
@@ -113,6 +142,29 @@ func (b *Builder) Add(str []rune, colelems [][]int) error {
e.elems[i] = append(e.elems[i], ce[0])
}
}
+ for i, ce := range e.elems {
+ isvar := false
+ for _, j := range variables {
+ if i == j {
+ isvar = true
+ }
+ }
+ if isvar {
+ if ce[0] >= b.minNonVar && b.minNonVar > 0 {
+ return fmt.Errorf("primary value %X of variable is larger than the smallest non-variable %X", ce[0], b.minNonVar)
+ }
+ if ce[0] > b.varTop {
+ b.varTop = ce[0]
+ }
+ } else if ce[0] > 0 {
+ if ce[0] <= b.varTop {
+ return fmt.Errorf("primary value %X of non-variable is smaller than the highest variable %X", ce[0], b.varTop)
+ }
+ if b.minNonVar == 0 || ce[0] < b.minNonVar {
+ b.minNonVar = ce[0]
+ }
+ }
+ }
elems, err := convertLargeWeights(e.elems)
if err != nil {
return err
@@ -123,13 +175,57 @@ func (b *Builder) Add(str []rune, colelems [][]int) error {
return nil
}
-// AddTailoring defines a tailoring x <_level y for the given locale.\n-// For example, AddTailoring(\"se\", \"z\", \"ä\", Primary) sorts \"ä\" after \"z\"\n-// at the primary level for Swedish. AddTailoring(\"de\", \"ue\", \"ü\", Secondary)\n-// sorts \"ü\" after \"ue\" at the secondary level for German.\n+// SetAnchor sets the point after which elements passed in subsequent calls to
+// Insert will be inserted. It is equivalent to the reset directive in an LDML
+// specification. See Insert for an example.
+// SetAnchor supports the following logical reset positions:
+// <first_tertiary_ignorable/>, <last_teriary_ignorable/>, <first_primary_ignorable/>,
+// and <last_non_ignorable/>.
+func (t *Tailoring) SetAnchor(anchor string) error {
+ // TODO: implement.
+ return nil
+}
+
+// SetAnchorBefore is similar to SetAnchor, except that subsequent calls to
+// Insert will insert entries before the anchor.
+func (t *Tailoring) SetAnchorBefore(anchor string) error {
+ // TODO: implement.
+ return nil
+}
+
+// Insert sets the ordering of str relative to the entry set by the previous
+// call to SetAnchor or Insert. The argument extend corresponds
+// to the extend elements as defined in LDML. A non-empty value for extend
+// will cause the collation elements corresponding to extend to be appended
+// to the collation elements generated for the entry added by Insert.
+// This has the same net effect as sorting str after the string anchor+extend.
// See http://www.unicode.org/reports/tr10/#Tailoring_Example for details
-// on parametric tailoring.\n-func (b *Builder) AddTailoring(locale, x, y string, l collate.Level) error {\n+// on parametric tailoring and http://unicode.org/reports/tr35/#Collation_Elements
+// for full details on LDML.
+//
+// Examples: create a tailoring for Swedish, where "ä" is ordered after "z"
+// at the primary sorting level:
+// t := b.Tailoring("se")
+// t.SetAnchor("z")
+// t.Insert(collate.Primary, "ä", "")
+// Order "ü" after "ue" at the secondary sorting level:
+// t.SetAnchor("ue")
+// t.Insert(collate.Secondary, "ü","")
+// or
+// t.SetAnchor("u")
+// t.Insert(collate.Secondary, "ü", "e")
+// Order "q" afer "ab" at the secondary level and "Q" after "q"
+// at the tertiary level:
+// t.SetAnchor("ab")
+// t.Insert(collate.Secondary, "q", "")
+// t.Insert(collate.Tertiary, "Q", "")
+// Order "b" before "a":
+// t.SetAnchorBefore("a")
+// t.Insert(collate.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 {
// TODO: implement.
return nil
}
@@ -189,7 +285,10 @@ func (b *Builder) error(e error) {\n func (b *Builder) build() (*table, error) {\n if !b.built {\n b.built = true
-\t\tb.t = &table{}\n+\t\tb.t = &table{\n+\t\t\tmaxContractLen: utf8.UTFMax,\n+\t\t\tvariableTop: uint32(b.varTop),\n+\t\t}\n \n b.simplify()\n b.processExpansions() // requires simplify
@@ -202,18 +301,23 @@ func (b *Builder) build() (*table, error) {\n return b.t, nil
}
-// Build builds a Collator for the given locale. To build the root table, set locale to "".\n-func (b *Builder) Build(locale string) (*collate.Collator, error) {\n+// Build builds the root Collator.\n+func (b *Builder) Build() (*collate.Collator, error) {
t, err := b.build()
if err != nil {
return nil, err
}
-\t// TODO: support multiple locales\n return collate.Init(t), nil
}
-// Print prints all tables to a Go file that can be included in\n-// the Collate package.\n+// Build builds a Collator for Tailoring t.\n+func (t *Tailoring) Build() (*collate.Collator, error) {
+ // TODO: implement.
+ return nil, nil
+}
+
+// Print prints the tables for b and all its Tailorings as a Go file
+// that can be included in the Collate package.
func (b *Builder) Print(w io.Writer) (int, error) {
t, err := b.build()
if err != nil {
コアとなるコードの解説
Builder
構造体とAdd
メソッドの変更
Builder
構造体にminNonVar
とvarTop
という新しいフィールドが追加されました。これらは、可変要素のプライマリ重みの範囲を追跡するために使用されます。Add
メソッドのシグネチャがfunc (b *Builder) Add(str []rune, colelems [][]int, variables []int) error
に変更されました。variables
引数は、colelems
内のどの要素が可変要素であるかを示すインデックスのリストです。Add
メソッドの内部で、variables
リストに基づいて各照合要素が可変要素であるかどうかがチェックされます。- 可変要素と非可変要素のプライマリ重みが
minNonVar
とvarTop
と比較され、UCAのルールに違反しないか(例: 可変要素のプライマリ重みが非可変要素の最小プライマリ重みより大きい、または非可変要素のプライマリ重みが可変要素の最大プライマリ重みより小さい)が検証されます。これにより、VariableTop
の適切な設定が保証されます。
Tailoring
構造体の導入と関連メソッド
Tailoring
という新しい構造体が定義されました。これは、特定のロケールに対するテーラリングを構築するためのものです。Builder.Tailoring(locale string) *Tailoring
メソッドが追加され、指定されたロケールに対応するTailoring
インスタンスを取得できるようになりました。Tailoring.SetAnchor(anchor string) error
とTailoring.SetAnchorBefore(anchor string) error
メソッドが追加されました。これらは、テーラリングにおいて新しい要素を挿入する基準点(アンカー)を設定するために使用されます。LDMLの<reset>
要素のセマンティクスを反映しています。Tailoring.Insert(level collate.Level, str, extend string) error
メソッドが追加されました。これは、SetAnchor
で設定されたアンカーに対して、指定されたレベルで文字列str
を挿入します。extend
引数はLDMLのextend
要素に対応し、str
の照合要素にextend
の照合要素を追加する効果を持ちます。
Builder.Build
メソッドの変更
func (b *Builder) Build() (*collate.Collator, error)
のように、引数からlocale string
が削除されました。これは、Builder
がルートテーブルの構築に特化し、テーラリングはTailoring
構造体とそのBuild
メソッド(Tailoring.Build() (*collate.Collator, error)
)で行われるようになったためです。Builder.build()
内部で、table
構造体の初期化時にvariableTop
がb.varTop
から設定されるようになりました。
collate.Collator
とcollate.table
の変更
collate.Collator
構造体からvariableTop
フィールドが削除されました。collate.table
構造体にvariableTop uint32
フィールドが追加されました。これにより、variableTop
の値が照合テーブル自体に紐付けられるようになり、Collator
はテーブルからこの値を取得するようになりました。collate.Init
関数(Collator
を初期化する内部関数)が、新しいtableInitializer
インターフェースを通じてvariableTop
を取得するように変更されました。
これらの変更により、照合テーブルの構築プロセスがより構造化され、特にCLDRの複雑なテーラリングルールを扱う際の柔軟性と正確性が向上しました。
関連リンク
- Unicode Collation Algorithm (UCA)
- Common Locale Data Repository (CLDR)
- Locale Data Markup Language (LDML)
- Go言語の
exp/locale/collate
パッケージのドキュメント (当時のもの、現在はgolang.org/x/text/collate
に移行)
参考にした情報源リンク
- Unicode Collation Algorithm - Wikipedia
- Common Locale Data Repository - Wikipedia
- LDML - Unicode Consortium
- Go言語の
x/text/collate
パッケージのソースコード (現在のバージョン) - Go言語の
x/text/collate/build
パッケージのソースコード (現在のバージョン) - Go言語の
x/text/collate/build/builder.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/build/maketables.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/collate.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/table.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/tables.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/export.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/export_test.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/table_test.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/build/builder_test.go
のソースコード (現在のバージョン) - Go言語の
x/text/collate/build/table.go
のソースコード (現在のバージョン)