[インデックス 1769] ファイルの概要
このコミットは、Go言語の標準ライブラリの一部である src/lib/unicode/letter.go
ファイルに対する変更です。このファイルは、Unicode文字のプロパティ、特に文字がアルファベットであるか、大文字であるかなどを判定するためのデータと関数を提供します。具体的には、Unicodeのコードポイント範囲を定義するRange
構造体、大文字の範囲を定義するUpper
、一般的な文字の範囲を定義するLetter
といった変数、そしてそれらの範囲内に特定のルーン(Unicodeコードポイント)が含まれるかを判定するIs
関数、IsUpper
関数、IsLetter
関数などが含まれています。
コミット
- コミットハッシュ:
b18e4184100e18c50b88d009487dd7a2841d093a
- 作者: Rob Pike r@golang.org
- コミット日時: 2009年3月6日 金曜日 03:22:02 -0800
- 変更ファイル:
src/lib/unicode/letter.go
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b18e4184100e18c50b88d009487dd7a2841d093a
元コミット内容
document unicode, such as it is
R=rsc
DELTA=18 (9 added, 0 deleted, 9 changed)
OCL=25817
CL=25832
変更の背景
このコミットは、Go言語の初期開発段階におけるUnicodeサポートのドキュメント化と、それに伴うAPIの改善を目的としています。
主な変更点は以下の通りです。
- ドキュメントの追加:
unicode
パッケージ、Range
構造体、Upper
、Letter
変数、IsUpper
、IsLetter
関数など、主要な要素にコメントが追加され、その役割が明確化されました。これは、Go言語の設計哲学において、コードの可読性とドキュメントの重要性が高く評価されていることを反映しています。 Range
構造体のフィールド名変更:Range
構造体のフィールド名がlo
,hi
,stride
からLo
,Hi
,Stride
へと変更されました。これはGo言語の可視性ルール(エクスポートルール)に則った変更であり、これらのフィールドがパッケージ外部からアクセス可能になることを意味します。これにより、unicode
パッケージを利用する他のパッケージが、Range
構造体の内部データに直接アクセスできるようになり、より柔軟な処理が可能になります。- コードの整合性: フィールド名変更に伴い、
Is
関数内の参照も新しいフィールド名に更新され、コード全体の整合性が保たれています。
Go言語は、その設計当初からUnicodeを完全にサポートすることを目標としており、このコミットはその初期段階におけるUnicode関連コードの整備の一環として行われました。特に、Goの設計者の一人であるRob Pike氏によるコミットであることから、Go言語の設計思想が色濃く反映されていると言えます。
前提知識の解説
Unicodeとコードポイント
Unicodeは、世界中のあらゆる文字を統一的に扱うための文字コードの国際標準です。各文字には一意の「コードポイント」と呼ばれる数値が割り当てられています。例えば、'A'はU+0041、'あ'はU+3042といった形で表現されます。Go言語では、文字列はUTF-8でエンコードされ、個々の文字は「ルーン(rune)」として扱われます。ルーンはint32
型で表現され、Unicodeのコードポイントに対応します。
Go言語の可視性ルール(エクスポート)
Go言語には、パッケージ内外からの識別子(変数、関数、構造体、フィールドなど)のアクセスを制御するシンプルなルールがあります。
- エクスポートされた識別子: 識別子の名前が大文字で始まる場合、その識別子はパッケージ外部からアクセス可能です(エクスポートされている)。
- エクスポートされていない識別子: 識別子の名前が小文字で始まる場合、その識別子はパッケージ内部からのみアクセス可能です(エクスポートされていない)。
このコミットにおけるRange
構造体のフィールド名変更(lo
-> Lo
など)は、この可視性ルールに直接関係しています。小文字だったフィールドが大文字に変更されたことで、これらのフィールドがunicode
パッケージの外部からも参照・利用できるようになりました。
Go言語のunicode
パッケージ
Go言語の標準ライブラリには、Unicode文字のプロパティを扱うためのunicode
パッケージが含まれています。このパッケージは、特定のルーンが数字であるか、文字であるか、空白文字であるか、大文字であるか、小文字であるかなどを判定する関数を提供します。また、Unicodeのカテゴリ情報やスクリプト情報なども提供し、多言語対応のアプリケーション開発を支援します。
Range
構造体
unicode
パッケージ内で定義されているRange
構造体は、Unicodeのコードポイントの連続した範囲を表現するために使用されます。
type Range struct {
Lo int // 範囲の開始コードポイント(含む)
Hi int // 範囲の終了コードポイント(含む)
Stride int // コードポイントの増分(通常は1)
}
この構造体は、特定の文字の集合(例: 大文字、数字など)を効率的に表現するために利用されます。Stride
は、範囲内のコードポイントが等間隔で並んでいる場合にその間隔を示します。例えば、Stride
が1であれば、Lo
からHi
までの全てのコードポイントが含まれます。
技術的詳細
このコミットの技術的な変更は、主にsrc/lib/unicode/letter.go
ファイル内の以下の点に集約されます。
-
パッケージコメントの追加:
--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -10,14 +10,19 @@ // link in only the tables that are used by the program, // etc. +// This package provides data and functions to test some properties of Unicode code points. +// It is rudimentary but will improve. package unicode
package unicode
の直前に、このパッケージがUnicodeコードポイントのプロパティをテストするためのデータと関数を提供すること、そしてまだ基本的な機能しか持たないが今後改善される予定であることが明記されました。これは、Go言語のドキュメンテーション規約に則ったもので、パッケージの目的を明確に示します。 -
Range
構造体のフィールド名変更とコメント追加:--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -10,14 +10,19 @@ // link in only the tables that are used by the program, // etc. +// This package provides data and functions to test some properties of Unicode code points. +// It is rudimentary but will improve. package unicode +// The representation of a range of Unicode code points. The range runs from Lo to Hi +// inclusive and has the specified stride. type Range struct { - lo int; - hi int; - stride int; + Lo int; + Hi int; + Stride int; }
Range
構造体のフィールド名がlo
,hi
,stride
からLo
,Hi
,Stride
へと変更されました。これにより、これらのフィールドはエクスポートされ、unicode
パッケージの外部から直接アクセスできるようになりました。また、各フィールドの役割を説明するコメントが追加され、構造体の意図がより明確になりました。 -
変数および関数へのコメント追加:
--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -150,6 +155,7 @@ var Upper = []Range{\n Range{0x1d7ca, 0x1d7ca, 1},\n }\n \n +// Letter is the set of Unicode letters.\n var Letter = []Range {\n Range{0x0041, 0x005a, 1},\n Range{0x0061, 0x007a, 1},\
Upper
変数とLetter
変数に、それぞれがUnicodeの大文字と文字の集合であることを示すコメントが追加されました。--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -559,10 +566,12 @@ func Is(ranges []Range, rune int) bool {\n return false;\n }\n \n +// IsLetter reports whether the rune is an upper case letter.\n func IsUpper(rune int) bool {\n return Is(Upper, rune);\n }\n \n +// IsLetter reports whether the rune is a letter.\n func IsLetter(rune int) bool {\n return Is(Letter, rune);\n }\
IsUpper
関数とIsLetter
関数に、それぞれがルーンが大文字であるか、文字であるかを報告することを示すコメントが追加されました。 -
Is
関数の内部ロジックの更新:--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -525,18 +531,19 @@ var Letter = []Range {\n Range{0x2f800, 0x2fa1d, 1},\n }\n \n +// Is tests whether rune is in the specified table of ranges.\n func Is(ranges []Range, rune int) bool {\n // common case: rune is ASCII or Latin-1\n if rune < 0x100 {\n for i := 0; i < len(ranges); i++ {\n r := ranges[i];\n - if rune > r.hi {\n + if rune > r.Hi {\n continue;\n }\n - if rune < r.lo {\n + if rune < r.Lo {\n return false;\n }\n - return (rune - r.lo) % r.stride == 0;\n + return (rune - r.Lo) % r.Stride == 0;\n }\n return false;\n }\
Is
関数内でRange
構造体のフィールドを参照している箇所が、r.lo
,r.hi
,r.stride
からr.Lo
,r.Hi
,r.Stride
へと変更されました。これは、Range
構造体のフィールド名変更に合わせた修正であり、コードの機能的な変更はありません。Is
関数は、与えられたルーンが指定されたRange
スライス内のいずれかの範囲に含まれるかを効率的に判定するための二分探索アルゴリズムを使用しています。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は、主にsrc/lib/unicode/letter.go
ファイル内の以下の部分です。
-
Range
構造体の定義変更:--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -10,14 +10,19 @@ // link in only the tables that are used by the program, // etc. +// This package provides data and functions to test some properties of Unicode code points. +// It is rudimentary but will improve. package unicode +// The representation of a range of Unicode code points. The range runs from Lo to Hi +// inclusive and has the specified stride. type Range struct { - lo int; - hi int; - stride int; + Lo int; + Hi int; + Stride int; }
Range
構造体のフィールド名が小文字から大文字に変更され、コメントが追加されました。 -
Is
関数内のRange
フィールド参照の更新:--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -525,18 +531,19 @@ var Letter = []Range {\n Range{0x2f800, 0x2fa1d, 1},\n }\n \n +// Is tests whether rune is in the specified table of ranges.\n func Is(ranges []Range, rune int) bool {\n // common case: rune is ASCII or Latin-1\n if rune < 0x100 {\n for i := 0; i < len(ranges); i++ {\n r := ranges[i];\n - if rune > r.hi {\n + if rune > r.Hi {\n continue;\n }\n - if rune < r.lo {\n + if rune < r.Lo {\n return false;\n }\n - return (rune - r.lo) % r.stride == 0;\n + return (rune - r.Lo) % r.Stride == 0;\n }\n return false;\n }\
Is
関数内のr.hi
,r.lo
,r.stride
への参照が、それぞれr.Hi
,r.Lo
,r.Stride
に更新されました。同様に、二分探索を行う後半のロジックも更新されています。--- a/src/lib/unicode/letter.go +++ b/src/lib/unicode/letter.go @@ -547,10 +554,10 @@ func Is(ranges []Range, rune int) bool {\n for lo < hi {\n m := lo + (hi - lo)/2;\n r := ranges[m];\n - if r.lo <= rune && rune <= r.hi {\n - return (rune - r.lo) % r.stride == 0;\n + if r.Lo <= rune && rune <= r.Hi {\n + return (rune - r.Lo) % r.Stride == 0;\n }\n - if rune < r.lo {\n + if rune < r.Lo {\n hi = m;\n } else {\n lo = m+1;\
コアとなるコードの解説
Range
構造体のフィールド名変更の意義
Go言語の可視性ルールにより、Range
構造体のフィールド名がlo
, hi
, stride
(小文字で始まる)からLo
, Hi
, Stride
(大文字で始まる)に変更されたことは、非常に重要な意味を持ちます。
- 変更前: フィールドが小文字で始まっていたため、これらのフィールドは
unicode
パッケージ内部からしかアクセスできませんでした。つまり、unicode
パッケージを利用する外部のコードは、Range
構造体のlo
,hi
,stride
の値に直接アクセスしたり、設定したりすることができませんでした。 - 変更後: フィールドが大文字で始まるようになったため、これらのフィールドはエクスポートされ、
unicode
パッケージの外部からも直接アクセス可能になりました。これにより、開発者はRange
構造体のインスタンスを作成し、そのLo
,Hi
,Stride
フィールドに直接値を設定したり、既存のRange
インスタンスのこれらの値を読み取ったりすることができるようになります。これは、unicode
パッケージの柔軟性と再利用性を高める上で大きな改善です。例えば、カスタムのUnicode範囲を定義してIs
関数に渡すようなシナリオが考えられます。
Is
関数内の参照更新
Is
関数は、与えられたルーンがranges
スライス内のいずれかのRange
に含まれるかを判定するロジックを実装しています。この関数は、Range
構造体のlo
, hi
, stride
フィールドにアクセスして、ルーンが範囲内にあるか、そしてstride
に従っているかをチェックします。
フィールド名がLo
, Hi
, Stride
に変更されたことに伴い、Is
関数内のこれらのフィールドへの参照もすべて更新されました。これは機能的な変更ではなく、APIの変更に合わせたコードの整合性を保つための修正です。これにより、Is
関数は引き続き正しく動作し、エクスポートされたRange
フィールドを利用してUnicodeルーンのプロパティを効率的に判定できます。
このコミットは、Go言語の初期段階におけるUnicodeサポートの基盤を固め、将来的な拡張性と使いやすさを考慮した設計が行われていたことを示しています。特に、Go言語のシンプルで一貫した可視性ルールが、このようなAPIの改善にどのように貢献しているかがよくわかります。
関連リンク
参考にした情報源リンク
- Go言語の公式ドキュメントおよび
unicode
パッケージのソースコード - Go言語の可視性ルールに関する一般的な情報源(Go言語のチュートリアルやブログ記事など)
- Unicodeに関する一般的な情報源(Wikipediaなど)