[インデックス 1230] ファイルの概要
このコミットは、Go言語の標準ライブラリにおける大規模な変更セット(チェンジリスト19916)の自動ロールバック(元に戻すこと)です。元の変更はビルドを壊したため、このロールバックが実行されました。具体的には、fmt
(フォーマット)、reflect
(リフレクション)、strconv
(文字列変換)、utf8
(UTF-8処理)パッケージに加えられた機能追加や修正が取り消されています。
コミット
commit 85fea81d70d0af531944cc6ceacf955b4a833901
Author: Russ Cox <rsc@golang.org>
Date: Mon Nov 24 13:24:15 2008 -0800
Automated g4 rollback of changelist 19916.
*** Reason for rollback ***
broke build
*** Original change description ***
utf8: add InString routines for decoding in strings
reflect: add InterfaceValue.Get(), remove Empty
strconv: add Quote, CanBackquote
fmt:
* %q go-quoted " string
* %#q go-quoted ` string if possible, " string otherwise
* %x hexadecimal string
* anywhere a string is okay, *[]byte is okay
* flags # 0 - + space
* print value inside interface, not interface itself
* tests
TBR=r
OCL=19920
CL=19920
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/85fea81d70d0af531944cc6ceacf955b4a833901
元コミット内容
このコミットはロールバックであるため、元のコミット(チェンジリスト19916)の内容は以下の通りです。
utf8
パッケージ: 文字列内でUTF-8デコードを行うためのInString
ルーチンが追加されました。reflect
パッケージ:InterfaceValue.Get()
メソッドが追加され、Empty
型が削除されました。strconv
パッケージ: 文字列をクォート(引用符で囲む)するためのQuote
関数と、バッククォート(CanBackquote
関数が追加されました。fmt
パッケージ:%q
フォーマット動詞が追加され、Go言語の文字列リテラル形式で文字列をクォートして出力できるようになりました。%#q
フォーマット動詞が追加され、可能であればバッククォートで、そうでなければ通常の引用符で文字列をクォートして出力できるようになりました。%x
フォーマット動詞が追加され、文字列を16進数形式で出力できるようになりました。- 文字列が許容される場所で
*[]byte
型も許容されるようになりました。 #
、0
、+
、-
、- インターフェース自体ではなく、インターフェース内の値を出力するようになりました。
- 関連するテストが追加・更新されました。
変更の背景
このコミットは、チェンジリスト19916の自動ロールバックです。ロールバックの理由は、元の変更が「ビルドを壊した」ためと明記されています。これは、Go言語のビルドシステムまたはテストスイートにおいて、チェンジリスト19916が導入された際に何らかのコンパイルエラー、リンクエラー、またはテストの失敗を引き起こしたことを意味します。安定した開発環境を維持するため、問題のある変更は迅速にロールバックされるのが一般的です。
前提知識の解説
- Go言語のパッケージ: Go言語は、関連する機能の集合を「パッケージ」として整理します。
fmt
: フォーマットされたI/O(入出力)を実装するパッケージです。Printf
やSprintf
などの関数を提供し、様々なデータ型を整形して文字列に出力する機能を持っています。フォーマット動詞(例:%d
、%s
)やフラグ(例:%05d
)を使って出力形式を制御します。reflect
: 実行時にプログラムの構造を検査・操作するための機能を提供するパッケージです。これにより、変数の型情報や値にアクセスしたり、メソッドを呼び出したりすることが可能になります。strconv
: 基本データ型(数値、真偽値など)と文字列との間の変換機能を提供するパッケージです。文字列のクォート(引用符付け)やアンクォート(引用符外し)なども扱います。utf8
: UTF-8エンコーディングされたテキストを扱うためのユーティリティ関数を提供するパッケージです。ルーン(Unicodeコードポイント)のデコードやエンコード、バイト列が完全なUTF-8ルーンを表しているかのチェックなどを行います。
g4
: Google内部で使用されていたバージョン管理システムPerforceのクライアントツールです。Go言語の初期開発はGoogle内部のPerforceシステムで行われていたため、コミットメッセージにg4
やchangelist
といった用語が見られます。- ロールバック: ソフトウェア開発において、以前のバージョンや状態に戻す操作のことです。問題のある変更が導入された際に、その変更を取り消して安定した状態に戻すために行われます。
- フォーマット動詞とフラグ:
fmt
パッケージで使用される特殊な記号で、値の出力形式を指定します。%q
: 文字列をGo言語の引用符で囲まれたリテラル形式で出力します。特殊文字はエスケープされます。%x
/%X
: 数値やバイト列を16進数形式で出力します。%x
は小文字、%X
は大文字を使用します。#
フラグ: 別の形式(例: 16進数に0x
プレフィックスを付ける)を使用したり、%q
でバッククォートを使用したりするなど、代替のフォーマットを指定します。0
フラグ: 数値のゼロパディングを指定します。-
フラグ: 左寄せを指定します。+
フラグ: 数値の符号(正の場合も+
)を常に表示します。
- インターフェース (Interface): Go言語における抽象型です。メソッドのシグネチャの集合を定義し、そのメソッドを実装する任意の型がそのインターフェースを満たすとされます。
技術的詳細
このコミットはチェンジリスト19916のロールバックであるため、以下の変更は取り消された内容として記述します。
fmt
パッケージの変更の取り消し:src/lib/fmt/fmt_test.go
が削除されました。これは、元の変更で追加されたテストが、このロールバックによって不要になったか、新しいテストフレームワークに移行されたことを示唆しています。実際に、test/fmt_test.go
という新しいテストファイルが追加されています。src/lib/fmt/format.go
では、Fmt
構造体からフォーマットフラグ(minus
,plus
,sharp
,space
,zero
)のフィールドが削除され、関連するフラグクリアロジックも削除されました。また、文字列のパディングロジックが簡素化され、ゼロパディングや符号表示に関する詳細な制御が取り除かれました。sx
(小文字16進数文字列)、sX
(大文字16進数文字列)、q
(クォート文字列)といった文字列フォーマット用のメソッドが削除されました。src/lib/fmt/print.go
では、getField
関数が削除され、reflect.InterfaceValue
から内部の値を取得するロジックが取り消されました。getString
関数における*[]byte
の特殊な扱いも削除されました。フォーマット文字列のパースロジックから、#
、0
、+
、-
、%x
、%X
、%q
といった新しいフォーマット動詞の処理ロジックも削除されました。getField
の呼び出しは、より直接的なv.Field(fieldnum)
に置き換えられました。
reflect
パッケージの変更の取り消し:src/lib/reflect/all_test.go
からTestInterfaceGet
テストが削除されました。src/lib/reflect/cast_amd64.s
からAddrToPtrInterface
とPtrInterfaceToAddr
というアセンブリ関数が削除されました。これらはインターフェース値とアドレス間の変換を扱うものでした。src/lib/reflect/gencast.sh
では、Interface
型が生成対象から除外される変更が取り消されました。src/lib/reflect/value.go
では、Empty
インターフェースの定義がコメントアウトされ、Value
インターフェースのInterface()
メソッドの戻り値型がinterface{}
からEmpty
に変更された部分が元に戻されました。InterfaceValue
インターフェースからGet()
メソッドが削除され、その実装も削除されました。NewValue
関数の引数型もEmpty
からinterface{}
に戻されました。
strconv
パッケージの変更の取り消し:src/lib/strconv/Makefile
では、quote.o
(quote.go
のコンパイル結果)がビルド対象から除外される変更が取り消され、再び含まれるようになりました。src/lib/strconv/ftoa_test.go
から浮動小数点数フォーマットに関する特定のテストケースが削除されました。src/lib/strconv/quote.go
とsrc/lib/strconv/quote_test.go
が完全に削除されました。これは、文字列のクォートとバッククォートに関する機能(Quote
とCanBackquote
関数)とそのテストが完全に削除されたことを意味します。
utf8
パッケージの変更の取り消し:src/lib/utf8.go
では、RuneMax
定数の値が変更され、DecodeRuneInStringInternal
、FullRuneInString
、DecodeRuneInString
といった文字列を直接扱うUTF-8デコードルーチンが削除されました。src/lib/utf8_test.go
では、FullRuneInString
やDecodeRuneInString
を使用していたテストが削除され、バイトスライスを扱うFullRune
やDecodeRune
に依存する形に戻されました。また、テストヘルパー関数CEscape
が追加されました。
全体として、このロールバックは、Go言語の初期段階におけるfmt
、reflect
、strconv
、utf8
パッケージの設計と実装に関する重要な変更が、ビルドの安定性を損なったために一時的に取り消されたことを示しています。特に、文字列の高度なフォーマット機能、リフレクションにおけるインターフェース値の扱い、そしてUTF-8文字列処理の最適化が、この時点ではまだ安定していなかったことが伺えます。
コアとなるコードの変更箇所
このコミットはロールバックであるため、以下の箇所が元の変更によって追加され、このコミットによって削除されたコアなコード変更箇所となります。
src/lib/fmt/format.go
:Fmt
構造体からフォーマットフラグ(minus
,plus
,sharp
,space
,zero
)の定義と、それらをクリアするclearflags()
内のロジックが削除されました。pad
メソッド内のパディング文字(padchar
)の選択ロジック(f.zero
による'0'
パディング)が削除され、常にスペースでパディングするようになりました。integer
メソッド内のゼロパディングと符号表示に関する詳細なロジック(prec
とzero
の相互作用、f.plus
やf.space
による符号の挿入)が削除されました。sx
,sX
,q
といった文字列フォーマット用のメソッドが完全に削除されました。
src/lib/fmt/print.go
:getField
関数が削除されました。この関数はreflect.InterfaceValue
から内部の値を取り出す役割を持っていました。getString
関数内の*[]byte
型を文字列として扱う特殊なケースが削除されました。doprintf
関数内のフォーマット文字列パースロジックから、#
,0
,+
,-
,doprintf
関数内のcase 'x'
,case 'X'
,case 'q'
といった新しいフォーマット動詞の処理ブロックが削除されました。
src/lib/reflect/value.go
:export type Empty interface {}
の定義が削除されました。InterfaceValue
インターフェースからGet()
メソッドの定義が削除され、InterfaceValueStruct
構造体からその実装も削除されました。NewValue
関数のシグネチャがexport func NewValue(e Empty) Value
からexport func NewValue(e interface {}) Value
に戻されました。
src/lib/strconv/quote.go
: ファイル全体が削除されました。これにより、Quote
関数とCanBackquote
関数が完全に失われました。src/lib/utf8.go
:DecodeRuneInStringInternal
,FullRuneInString
,DecodeRuneInString
といった、文字列を直接引数に取るUTF-8デコード関連の関数が削除されました。
コアとなるコードの解説
このロールバックによって削除された(元のコミットで追加された)コアなコードは、Go言語の初期の設計思想と実装の進化を反映しています。
fmt
パッケージの変更: 元のコミットでは、fmt
パッケージにC言語のprintf
ライクな機能(特にフラグによる詳細な制御)と、Go言語特有の文字列クォート(%q
,%#q
)やバイト列の16進数表示(%x
,%X
)が導入されようとしていました。これらの機能は、より柔軟で表現力豊かなフォーマットを可能にするものでしたが、ビルドを壊したため、この時点では安定した実装が困難であったか、既存のコードベースとの互換性問題を引き起こした可能性があります。特に、*[]byte
を文字列として扱えるようにする変更は、型システムにおける暗黙の変換や、バイト列と文字列の厳密な区別というGoの原則に反する可能性があり、問題の原因となったかもしれません。reflect
パッケージの変更:InterfaceValue.Get()
の追加は、リフレクションを通じてインターフェースの内部に格納された具体的な値に直接アクセスする手段を提供しようとしたものです。Empty
インターフェースの導入は、おそらくinterface{}
の別名または特定の用途に特化したインターフェースとして試みられたものですが、これもリフレクションの設計に複雑さをもたらしたか、意図しない副作用を引き起こした可能性があります。これらの変更のロールバックは、リフレクションのAPI設計がまだ流動的であり、安定したインターフェースを提供するための試行錯誤が行われていたことを示しています。strconv
パッケージの変更:Quote
とCanBackquote
関数の削除は、文字列のクォート処理がstrconv
パッケージから切り離されたことを意味します。これは、クォート処理がfmt
パッケージの内部機能として統合されるか、あるいはより汎用的なユーティリティとして再設計される必要があったことを示唆しています。特に、バッククォートの扱いはGo言語の文字列リテラルの特殊な形式であり、その適切な処理は複雑さを伴います。utf8
パッケージの変更:InString
ルーチンの削除は、UTF-8デコードがバイトスライスに対して行われるのが基本であり、文字列を直接引数に取るデコード関数は、パフォーマンスやメモリ割り当ての観点から最適ではなかったか、あるいは設計上の問題があったことを示唆しています。Go言語では文字列は不変のバイトスライスとして扱われるため、文字列を直接操作するよりもバイトスライスとして扱う方が効率的な場合があります。
このロールバックは、Go言語の初期開発において、機能追加と安定性のバランスを取ることの難しさ、そしてAPI設計における試行錯誤の過程を明確に示しています。ビルドの破損という具体的な問題が、これらの変更を一時的に撤回する決定的な要因となりました。
関連リンク
参考にした情報源リンク
- コミットメッセージ (commit 85fea81d70d0af531944cc6ceacf955b4a833901)
- GitHub上のコミット差分 (https://github.com/golang/go/commit/85fea81d70d0af531944cc6ceacf955b4a833901)
- Go言語の公式ドキュメント(
fmt
,reflect
,strconv
,utf8
パッケージに関する一般的な情報) - Go言語の歴史と設計に関する一般的な知識