[インデックス 1484] ファイルの概要
このコミットでは、主にGo言語の標準ライブラリの一部である src/lib/flag.go
と src/lib/fmt/fmt_test.go
の2つのファイルが変更されています。
コミット
commit 1d74892178931de5835da7ea09ed07f7dfe452c2
Author: Rob Pike <r@golang.org>
Date: Thu Jan 15 16:03:27 2009 -0800
more casifying fixups
R=rsc
DELTA=213 (0 added, 0 deleted, 213 changed)
OCL=22878
CL=22882
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1d74892178931de5835da7ea09ed07f7dfe452c2
元コミット内容
more casifying fixups
変更の背景
このコミットの背景にあるのは、Go言語における識別子の命名規則、特に「可視性(Visibility)」の原則を徹底することです。Go言語では、識別子(変数、関数、型、メソッドなど)の最初の文字が大文字であるか小文字であるかによって、その識別子がパッケージ外にエクスポートされる(公開される)か、パッケージ内部に限定される(非公開となる)かが決まります。
コミットメッセージの「casifying fixups」という表現は、この「大文字・小文字の区別による可視性」に関する修正、すなわち、本来パッケージ内部でのみ使用されるべき識別子が誤って大文字で始まっていたものを、小文字で始まる名前に変更することで、その可視性を適切に「非公開」に修正する作業を指しています。これにより、APIの明確性が向上し、外部からの不適切なアクセスを防ぎ、パッケージの内部実装と公開APIの境界がより明確になります。
前提知識の解説
Go言語の命名規則と可視性
Go言語の設計思想の一つに「シンプルさ」と「明示性」があります。その一環として、識別子の可視性に関する非常にシンプルなルールが設けられています。
- エクスポートされた識別子 (Exported Identifiers): 識別子の最初の文字が大文字である場合、その識別子はエクスポートされます。これは、その識別子が定義されているパッケージの外部からアクセス可能であることを意味します。例えば、
fmt.Println
のPrintln
は大文字で始まるため、fmt
パッケージの外部から呼び出すことができます。これは、他の言語におけるpublic
メンバーに相当します。 - エクスポートされない識別子 (Unexported Identifiers): 識別子の最初の文字が小文字である場合、その識別子はエクスポートされません。これは、その識別子が定義されているパッケージの内部からのみアクセス可能であることを意味します。他のパッケージからは直接アクセスできません。例えば、
fmt
パッケージ内部のヘルパー関数が小文字で始まる場合、それはfmt
パッケージの内部実装の詳細であり、外部からは利用できません。これは、他の言語におけるprivate
またはinternal
メンバーに相当します。
このルールは、Goの標準ライブラリ全体で厳密に守られており、APIの安定性と保守性を高める上で非常に重要です。
flag
パッケージ
flag
パッケージは、Goプログラムがコマンドライン引数を解析するための標準ライブラリです。プログラムの起動時に -name=value
の形式で渡されるフラグ(オプション)を定義し、その値をプログラム内で利用できるようにします。例えば、go run main.go -verbose=true
のようなコマンドライン引数を処理する際に使用されます。
fmt
パッケージ
fmt
パッケージは、Go言語におけるフォーマットI/O(入出力)を扱うための標準ライブラリです。C言語の printf
や scanf
に似た機能を提供し、文字列、数値、構造体などの値を整形して出力したり、入力から値を読み取ったりするために使用されます。fmt.Println
や fmt.Sprintf
などがよく知られています。
テストファイル (_test.go
)
Go言語では、テストコードは通常、テスト対象のソースファイルと同じディレクトリに _test.go
というサフィックスを持つファイルとして配置されます。例えば、fmt.go
のテストは fmt_test.go
に書かれます。これらのテストファイルは、go test
コマンドによって自動的に発見され、実行されます。テストコードも通常のGoコードと同様に命名規則に従う必要があります。
技術的詳細
このコミットの技術的な詳細は、Go言語の命名規則、特に内部的な(非公開の)識別子を小文字で始めるという慣習を、既存のコードベースに適用した点に集約されます。
具体的には、以下の変更が行われています。
-
src/lib/flag.go
における変更:flag
パッケージ内で定義されている各種の「値」を表す構造体(例:BoolValue
,IntValue
,StringValue
など)が、それぞれboolValue
,intValue
,stringValue
のように、先頭が大文字から小文字に変更されました。これにより、これらの構造体はパッケージ外部からは直接参照できなくなり、flag
パッケージの内部実装の詳細として扱われるようになります。- これらの構造体のコンストラクタ関数(例:
NewBoolValue
)も、対応する構造体名に合わせてnewBoolValue
のように小文字で始まる名前に変更されました。 Value
インターフェースのメソッドStr()
がstr()
に変更されました。これは、このメソッドがインターフェースの一部として公開されるべきではない、あるいは内部的なヘルパーメソッドとして扱われるべきであるという判断に基づいています。- フラグの集合を管理する型
Flags
がallFlags
に、そのコンストラクタNew()
がNew()
のままであるものの、内部で利用されるflags
変数の型が*Flags
から*allFlags
に変更されました。また、フラグを追加する内部関数Add
がadd
に変更されました。 ParseOne
メソッドのレシーバ型も*Flags
から*allFlags
に変更されています。- これらの変更により、
flag
パッケージの公開API(flag.Bool
,flag.Int
など)はそのまま維持しつつ、その内部実装に使われる型や関数が明確に非公開化され、パッケージの利用者が誤って内部実装に依存することを防ぎます。
-
src/lib/fmt/fmt_test.go
における変更:fmt
パッケージのテストコード内で定義されているテスト用の構造体(例:FmtTest
,FlagPrinter
,FlagTest
)が、それぞれfmtTest
,flagPrinter
,flagTest
のように小文字で始まる名前に変更されました。- テスト用の定数(例:
B32
,B64
)もb32
,b64
のように小文字で始まる名前に変更されました。 - これらの変更は、テストコード内の識別子もGoの命名規則に従い、テストファイル内でしか使用されない内部的な要素であることを明確にするためのものです。
これらの変更は、機能的な変更を伴わず、コードの可読性、保守性、そしてAPIの設計原則への準拠を向上させるための純粋なリファクタリングです。Go言語の初期段階において、コードベース全体で一貫した命名規則を確立するための重要なステップであったと考えられます。
コアとなるコードの変更箇所
src/lib/flag.go
--- a/src/lib/flag.go
+++ b/src/lib/flag.go
@@ -96,125 +96,125 @@ func atob(str string) (value bool, ok bool) {
}
type (
- BoolValue struct;
- IntValue struct;
- Int64Value struct;
- UintValue struct;
- Uint64Value struct;
- StringValue struct;
+ boolValue struct;
+ intValue struct;
+ int64Value struct;
+ uintValue struct;
+ uint64Value struct;
+ stringValue struct;
)
// -- Bool Value
-type BoolValue struct {
+type boolValue struct {
p *bool;
}
-func NewBoolValue(val bool, p *bool) *BoolValue {
+func newBoolValue(val bool, p *bool) *boolValue {
*p = val;
- return &BoolValue{p}
+ return &boolValue{p}
}
-func (b *BoolValue) Set(val bool) {
+func (b *boolValue) set(val bool) {
*b.p = val;
}
-func (b *BoolValue) Str() string {
+func (b *boolValue) str() string {
return fmt.Sprintf("%v", *b.p)
}
// -- Int Value
-type IntValue struct {
+type intValue struct {
p *int;
}
-func NewIntValue(val int, p *int) *IntValue {
+func newIntValue(val int, p *int) *intValue {
*p = val;
- return &IntValue{p}
+ return &intValue{p}
}
-func (i *IntValue) Set(val int) {
+func (i *intValue) set(val int) {
*i.p = val;
}
-func (i *IntValue) Str() string {
+func (i *intValue) str() string {
return fmt.Sprintf("%v", *i.p)
}
// -- Int64 Value
-type Int64Value struct {
+type int64Value struct {
p *int64;
}
-func NewInt64Value(val int64, p *int64) *Int64Value {
+func newInt64Value(val int64, p *int64) *int64Value {
*p = val;
- return &Int64Value{p}
+ return &int64Value{p}
}
-func (i *Int64Value) Set(val int64) {
+func (i *int64Value) set(val int64) {
*i.p = val;
}
-func (i *Int64Value) Str() string {
+func (i *int64Value) str() string {
return fmt.Sprintf("%v", *i.p)
}
// -- Uint Value
-type UintValue struct {
+type uintValue struct {
p *uint;
}
-func NewUintValue(val uint, p *uint) *UintValue {
+func newUintValue(val uint, p *uint) *uintValue {
*p = val;
- return &UintValue{p}
+ return &uintValue{p}
}
-func (i *UintValue) Set(val uint) {
+func (i *uintValue) set(val uint) {
*i.p = val
}
-func (i *UintValue) Str() string {
+func (i *uintValue) str() string {
return fmt.Sprintf("%v", *i.p)
}
-// -- Uint64 Value
-type Uint64Value struct {
+// -- uint64 Value
+type uint64Value struct {
p *uint64;
}
-func NewUint64Value(val uint64, p *uint64) *Uint64Value {
+func newUint64Value(val uint64, p *uint64) *uint64Value {
*p = val;
- return &Uint64Value{p}
+ return &uint64Value{p}
}
-func (i *Uint64Value) Set(val uint64) {
+func (i *uint64Value) set(val uint64) {
*i.p = val;
}
-func (i *Uint64Value) Str() string {
+func (i *uint64Value) str() string {
return fmt.Sprintf("%v", *i.p)
}
-// -- String Value
-type StringValue struct {
+// -- string Value
+type stringValue struct {
p *string;
}
-func NewStringValue(val string, p *string) *StringValue {
+func newStringValue(val string, p *string) *stringValue {
*p = val;
- return &StringValue{p}
+ return &stringValue{p}
}
-func (s *StringValue) Set(val string) {
+func (s *stringValue) set(val string) {
*s.p = val;
}
-func (s *StringValue) Str() string {
+func (s *stringValue) str() string {
return fmt.Sprintf("%#q", *s.p)
}
// -- Value interface
type Value interface {
-\tStr() string;
+\tstr() string;
}
// -- Flag structure (internal)
@@ -224,26 +224,26 @@ export type Flag struct {\n value Value;\n }\n \n-type Flags struct {\n+type allFlags struct {\n actual map[string] *Flag;\n formal map[string] *Flag;\n first_arg int;\n }\n \n \n-func New() *Flags {\n-\tf := new(Flags);\
+func New() *allFlags {\n+\tf := new(allFlags);\
\tf.first_arg = 1;\t// 0 is the program name, 1 is first arg\n \tf.actual = make(map[string] *Flag);\n \tf.formal = make(map[string] *Flag);\n \treturn f;\n }\n \n-var flags *Flags = New();\
+var flags *allFlags = New();\
\n export func PrintDefaults() {\n \tfor k, f := range flags.formal {\n-\t\tprint(" -", f.name, "=", f.value.Str(), ": ", f.usage, "\\n");\
+\t\tprint(" -", f.name, "=", f.value.str(), ": ", f.usage, "\\n");
\t}\n }\n \n@@ -273,7 +273,7 @@ export func NArg() int {\n \treturn sys.argc() - flags.first_arg\n }\n \n-func Add(name string, value Value, usage string) {\
+func add(name string, value Value, usage string) {\
\tf := new(Flag);\
\tf.name = name;\
\tf.usage = usage;\
@@ -288,65 +288,65 @@ func Add(name string, value Value, usage string) {\n \n export func Bool(name string, value bool, usage string) *bool {\n \tp := new(bool);\
-\tAdd(name, NewBoolValue(value, p), usage);\
+\tadd(name, newBoolValue(value, p), usage);\
\treturn p;\n }\n \n export func BoolVar(p *bool, name string, value bool, usage string) {\n-\tAdd(name, NewBoolValue(value, p), usage);\
+\tadd(name, newBoolValue(value, p), usage);\
}\n \n export func Int(name string, value int, usage string) *int {\n \tp := new(int);\
-\tAdd(name, NewIntValue(value, p), usage);\
+\tadd(name, newIntValue(value, p), usage);\
\treturn p;\n }\n \n export func IntVar(p *int, name string, value int, usage string) {\n-\tAdd(name, NewIntValue(value, p), usage);\
+\tadd(name, newIntValue(value, p), usage);\
}\n \n export func Int64(name string, value int64, usage string) *int64 {\n \tp := new(int64);\
-\tAdd(name, NewInt64Value(value, p), usage);\
+\tadd(name, newInt64Value(value, p), usage);\
\treturn p;\n }\n \n export func Int64Var(p *int64, name string, value int64, usage string) {\n-\tAdd(name, NewInt64Value(value, p), usage);\
+\tadd(name, newInt64Value(value, p), usage);\
}\n \n export func Uint(name string, value uint, usage string) *uint {\n \tp := new(uint);\
-\tAdd(name, NewUintValue(value, p), usage);\
+\tadd(name, newUintValue(value, p), usage);\
\treturn p;\n }\n \n export func UintVar(p *uint, name string, value uint, usage string) {\n-\tAdd(name, NewUintValue(value, p), usage);\
+\tadd(name, newUintValue(value, p), usage);\
}\n \n export func Uint64(name string, value uint64, usage string) *uint64 {\n \tp := new(uint64);\
-\tAdd(name, NewUint64Value(value, p), usage);\
+\tadd(name, newUint64Value(value, p), usage);\
\treturn p;\n }\n \n export func Uint64Var(p *uint64, name string, value uint64, usage string) {\n-\tAdd(name, NewUint64Value(value, p), usage);\
+\tadd(name, newUint64Value(value, p), usage);\
}\n \n export func String(name, value string, usage string) *string {\n \tp := new(string);\
-\tAdd(name, NewStringValue(value, p), usage);\
+\tadd(name, newStringValue(value, p), usage);\
\treturn p;\n }\n \n export func StringVar(p *string, name, value string, usage string) {\n-\tAdd(name, NewStringValue(value, p), usage);\
+\tadd(name, newStringValue(value, p), usage);\
}\n \n-func (f *Flags) ParseOne(index int) (ok bool, next int)\
+func (f *allFlags) ParseOne(index int) (ok bool, next int)\
{\n \ts := sys.argv(index);\
\tf.first_arg = index; // until proven otherwise\n@@ -394,16 +394,16 @@ func (f *Flags) ParseOne(index int) (ok bool, next int)\n \t\tprint("flag provided but not defined: -", name, "\\n");\n \t\tUsage();\n \t}\n-\tif f, ok := flag.value.(*BoolValue); ok {\
+\tif f, ok := flag.value.(*boolValue); ok {\
\t\tif has_value {\n \t\t\tk, ok := atob(value);\
\t\t\tif !ok {\n \t\t\t\tprint("invalid boolean value ", value, " for flag: -", name, "\\n");\n \t\t\t\tUsage();\n \t\t\t}\n-\t\t\tf.Set(k)\
+\t\t\tf.set(k)\
\t\t} else {\n-\t\t\tf.Set(true)\
+\t\t\tf.set(true)\
\t\t}\n \t} else {\n \t\t// It must have a value, which might be the next argument.\n@@ -417,8 +417,8 @@ func (f *Flags) ParseOne(index int) (ok bool, next int)\n \t\t\tprint("flag needs an argument: -", name, "\\n");\n \t\t\tUsage();\n \t\t}\n-\t\tif f, ok := flag.value.(*StringValue); ok {\
-\t\t\tf.Set(value)\
+\t\tif f, ok := flag.value.(*stringValue); ok {\
+\t\t\tf.set(value)\
\t\t} else {\n \t\t\t// It's an integer flag. TODO(r): check for overflow?\n \t\t\tk, ok := atoi(value);\
@@ -426,14 +426,14 @@ func (f *Flags) ParseOne(index int) (ok bool, next int)\n \t\t\t\tprint("invalid integer value ", value, " for flag: -", name, "\\n");\n \t\t\t\tUsage();\n \t\t\t}\n-\t\t\tif f, ok := flag.value.(*IntValue); ok {\
-\t\t\t\tf.Set(int(k));\
-\t\t\t} else if f, ok := flag.value.(*Int64Value); ok {\
-\t\t\t\tf.Set(k);\
-\t\t\t} else if f, ok := flag.value.(*UintValue); ok {\
-\t\t\t\tf.Set(uint(k));\
-\t\t\t} else if f, ok := flag.value.(*Uint64Value); ok {\
-\t\t\t\tf.Set(uint64(k));\
+\t\t\tif f, ok := flag.value.(*intValue); ok {\
+\t\t\t\tf.set(int(k));\
+\t\t\t} else if f, ok := flag.value.(*int64Value); ok {\
+\t\t\t\tf.set(k);\
+\t\t\t} else if f, ok := flag.value.(*uintValue); ok {\
+\t\t\t\tf.set(uint(k));\
+\t\t\t} else if f, ok := flag.value.(*uint64Value); ok {\
+\t\t\t\tf.set(uint64(k));
\t\t\t}\n \t\t}\n \t}\
src/lib/fmt/fmt_test.go
--- a/src/lib/fmt/fmt_test.go
+++ b/src/lib/fmt/fmt_test.go
@@ -20,134 +20,134 @@ export func TestFmtInterface(t *testing.T) {
}
}
-type FmtTest struct {
+type fmtTest struct {
fmt string;
val interface { };
out string;
}
-const B32 uint32 = 1<<32 - 1
-const B64 uint64 = 1<<64 - 1
+const b32 uint32 = 1<<32 - 1
+const b64 uint64 = 1<<64 - 1
var array = []int{1, 2, 3, 4, 5}
-var fmttests = []FmtTest{
+var fmttests = []fmtTest{
// basic string
-\tFmtTest{ "%s", "abc", "abc" },
-\tFmtTest{ "%x", "abc", "616263" },
-\tFmtTest{ "%x", "xyz", "78797a" },
-\tFmtTest{ "%X", "xyz", "78797A" },
-\tFmtTest{ "%q", "abc", `"abc"` },
+\tfmtTest{ "%s", "abc", "abc" },
+\tfmtTest{ "%x", "abc", "616263" },
+\tfmtTest{ "%x", "xyz", "78797a" },
+\tfmtTest{ "%X", "xyz", "78797A" },
+\tfmtTest{ "%q", "abc", `"abc"` },
// basic bytes
-\tFmtTest{ "%s", io.StringBytes("abc"), "abc" },
-\tFmtTest{ "%x", io.StringBytes("abc"), "616263" },
-\tFmtTest{ "% x", io.StringBytes("abc"), "61 62 63" },
-\tFmtTest{ "%x", io.StringBytes("xyz"), "78797a" },
-\tFmtTest{ "%X", io.StringBytes("xyz"), "78797A" },
-\tFmtTest{ "%q", io.StringBytes("abc"), `"abc"` },
+\tfmtTest{ "%s", io.StringBytes("abc"), "abc" },
+\tfmtTest{ "%x", io.StringBytes("abc"), "616263" },
+\tfmtTest{ "% x", io.StringBytes("abc"), "61 62 63" },
+\tfmtTest{ "%x", io.StringBytes("xyz"), "78797a" },
+\tfmtTest{ "%X", io.StringBytes("xyz"), "78797A" },
+\tfmtTest{ "%q", io.StringBytes("abc"), `"abc"` },
// escaped strings
-\tFmtTest{ "%#q", `abc`, "`abc`" },
-\tFmtTest{ "%#q", `"`, "`\"`" },
-\tFmtTest{ "1 %#q", `\n`, "1 `\\n`" },
-\tFmtTest{ "2 %#q", "\n", `2 "\n"` },
-\tFmtTest{ "%q", `"`, `"\""` },
-\tFmtTest{ "%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"` },
-\tFmtTest{ "%q", "abc\xffdef", `"abc\xffdef"` },
-\tFmtTest{ "%q", "\u263a", `"\u263a"` },
-\tFmtTest{ "%q", "\U0010ffff", `"\U0010ffff"` },
+\tfmtTest{ "%#q", `abc`, "`abc`" },
+\tfmtTest{ "%#q", `"`, "`\"`" },
+\tfmtTest{ "1 %#q", `\n`, "1 `\\n`" },
+\tfmtTest{ "2 %#q", "\n", `2 "\n"` },
+\tfmtTest{ "%q", `"`, `"\""` },
+\tfmtTest{ "%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"` },
+\tfmtTest{ "%q", "abc\xffdef", `"abc\xffdef"` },
+\tfmtTest{ "%q", "\u263a", `"\u263a"` },
+\tfmtTest{ "%q", "\U0010ffff", `"\U0010ffff"` },
// width
-\tFmtTest{ "%5s", "abc", " abc" },
-\tFmtTest{ "%-5s", "abc", "abc " },
-\tFmtTest{ "%05s", "abc", "00abc" },
+\tfmtTest{ "%5s", "abc", " abc" },
+\tfmtTest{ "%-5s", "abc", "abc " },
+\tfmtTest{ "%05s", "abc", "00abc" },
// integers
-\tFmtTest{ "%d", 12345, "12345" },
-\tFmtTest{ "%d", -12345, "-12345" },
-\tFmtTest{ "%10d", 12345, " 12345" },
-\tFmtTest{ "%10d", -12345, " -12345" },
-\tFmtTest{ "%+10d", 12345, " +12345" },
-\tFmtTest{ "%010d", 12345, "0000012345" },
-\tFmtTest{ "%010d", -12345, "-000012345" },
-\tFmtTest{ "%-10d", 12345, "12345 " },
-\tFmtTest{ "%010.3d", 1, " 001" },
-\tFmtTest{ "%010.3d", -1, " -001" },
-\tFmtTest{ "%+d", 12345, "+12345" },
-\tFmtTest{ "%+d", -12345, "-12345" },
-\tFmtTest{ "% d", 12345, " 12345" },
-\tFmtTest{ "% d", -12345, "-12345" },
+\tfmtTest{ "%d", 12345, "12345" },
+\tfmtTest{ "%d", -12345, "-12345" },
+\tfmtTest{ "%10d", 12345, " 12345" },
+\tfmtTest{ "%10d", -12345, " -12345" },
+\tfmtTest{ "%+10d", 12345, " +12345" },
+\tfmtTest{ "%010d", 12345, "0000012345" },
+\tfmtTest{ "%010d", -12345, "-000012345" },
+\tfmtTest{ "%-10d", 12345, "12345 " },
+\tfmtTest{ "%010.3d", 1, " 001" },
+\tfmtTest{ "%010.3d", -1, " -001" },
+\tfmtTest{ "%+d", 12345, "+12345" },
+\tfmtTest{ "%+d", -12345, "-12345" },
+\tfmtTest{ "% d", 12345, " 12345" },
+\tfmtTest{ "% d", -12345, "-12345" },
// arrays
// TODO: when arrays work in interfaces, enable this line
// and delete the TestArrayPrinter routine below
-\t// FmtTest{ "%v", array, "[1 2 3 4 5]" },
-\tFmtTest{ "%v", &array, "&[1 2 3 4 5]" },
+\t// fmtTest{ "%v", array, "[1 2 3 4 5]" },
+\tfmtTest{ "%v", &array, "&[1 2 3 4 5]" },
// old test/fmt_test.go
-\tFmtTest{ "%d", 1234, "1234" },
-\tFmtTest{ "%d", -1234, "−1234" },
-\tFmtTest{ "%d", uint(1234), "1234" },
-\tFmtTest{ "%d", uint32(B32), "4294967295" },
-\tFmtTest{ "%d", uint64(B64), "18446744073709551615" },
-\tFmtTest{ "%o", 01234, "1234" },
-\tFmtTest{ "%o", uint32(B32), "37777777777" },
-\tFmtTest{ "%o", uint64(B64), "1777777777777777777777" },
-\tFmtTest{ "%x", 0x1234abcd, "1234abcd" },
-\tFmtTest{ "%x", B32-0x1234567, "fedcba98" },
-\tFmtTest{ "%X", 0x1234abcd, "1234ABCD" },
-\tFmtTest{ "%X", B32-0x1234567, "FEDCBA98" },
-\tFmtTest{ "%x", B64, "ffffffffffffffff" },
-\tFmtTest{ "%b", 7, "111" },
-\tFmtTest{ "%b", B64, "1111111111111111111111111111111111111111111111111111111111111111" },
-\tFmtTest{ "%e", float64(1), "1.000000e+00" },
-\tFmtTest{ "%e", float64(1234.5678e3), "1.234568e+06" },
-\tFmtTest{ "%e", float64(1234.5678e-8), "1.234568e-05" },
-\tFmtTest{ "%e", float64(-7), "-7.000000e+00" },
-\tFmtTest{ "%e", float64(-1e-9), "-1.000000e-09" },
-\tFmtTest{ "%f", float64(1234.5678e3), "1234567.800000" },
-\tFmtTest{ "%f", float64(1234.5678e-8), "0.000012" },
-\tFmtTest{ "%f", float64(-7), "-7.000000" },
-\tFmtTest{ "%f", float64(-1e-9), "-0.000000" },
-\tFmtTest{ "%g", float64(1234.5678e3), "1.2345678e+06" },
-\tFmtTest{ "%g", float32(1234.5678e3), "1.2345678e+06" },
-\tFmtTest{ "%g", float64(1234.5678e-8), "1.2345678e-05" },
-\tFmtTest{ "%g", float64(-7), "-7" },
-\tFmtTest{ "%g", float64(-1e-9), "-1e-09", },
-\tFmtTest{ "%g", float32(-1e-9), "-1e-09" },
-\tFmtTest{ "%c", 'x', "x" },
-\tFmtTest{ "%c", 0xe4, "ä" },
-\tFmtTest{ "%c", 0x672c, "本" },
-\tFmtTest{ "%c", '日', "日" },
-\tFmtTest{ "%20.8d", 1234, " 00001234" },
-\tFmtTest{ "%20.8d", -1234, " -00001234" },
-\tFmtTest{ "%20d", 1234, " 1234" },
-\tFmtTest{ "%-20.8d", 1234, "00001234 " },
-\tFmtTest{ "%-20.8d", -1234, "-00001234 " },
-\tFmtTest{ "%.20b", 7, "00000000000000000111" },
-\tFmtTest{ "%20.5s", "qwertyuiop", " qwert" },
-\tFmtTest{ "%.5s", "qwertyuiop", "qwert" },
-\tFmtTest{ "%-20.5s", "qwertyuiop", "qwert " },
-\tFmtTest{ "%20c", 'x', " x" },
-\tFmtTest{ "%-20c", 'x', "x " },
-\tFmtTest{ "%20.6e", 1.2345e3, " 1.234500e+03" },
-\tFmtTest{ "%20.6e", 1.2345e-3, " 1.234500e-03" },
-\tFmtTest{ "%20e", 1.2345e3, " 1.234500e+03" },
-\tFmtTest{ "%20e", 1.2345e-3, " 1.234500e-03" },
-\tFmtTest{ "%20.8e", 1.2345e3, " 1.23450000e+03" },
-\tFmtTest{ "%20f", float64(1.23456789e3), " 1234.567890" },
-\tFmtTest{ "%20f", float64(1.23456789e-3), " 0.001235" },
-\tFmtTest{ "%20f", float64(12345678901.23456789), " 12345678901.234568" },
-\tFmtTest{ "%-20f", float64(1.23456789e3), "1234.567890 " },
-\tFmtTest{ "%20.8f", float64(1.23456789e3), " 1234.56789000" },
-\tFmtTest{ "%20.8f", float64(1.23456789e-3), " 0.00123457" },
-\tFmtTest{ "%g", float64(1.23456789e3), "1234.56789" },
-\tFmtTest{ "%g", float64(1.23456789e-3), "0.00123456789" },
-\tFmtTest{ "%g", float64(1.23456789e20), "1.23456789e+20" },
-\tFmtTest{ "%20e", sys.Inf(1), " +Inf" },
-\tFmtTest{ "%-20f", sys.Inf(-1), "-Inf " },
-\tFmtTest{ "%20g", sys.NaN(), " NaN" },
+\tfmtTest{ "%d", 1234, "1234" },
+\tfmtTest{ "%d", -1234, "-1234" },
+\tfmtTest{ "%d", uint(1234), "1234" },
+\tfmtTest{ "%d", uint32(b32), "4294967295" },
+\tfmtTest{ "%d", uint64(b64), "18446744073709551615" },
+\tfmtTest{ "%o", 01234, "1234" },
+\tfmtTest{ "%o", uint32(b32), "37777777777" },
+\tfmtTest{ "%o", uint64(b64), "1777777777777777777777" },
+\tfmtTest{ "%x", 0x1234abcd, "1234abcd" },
+\tfmtTest{ "%x", b32-0x1234567, "fedcba98" },
+\tfmtTest{ "%X", 0x1234abcd, "1234ABCD" },
+\tfmtTest{ "%X", b32-0x1234567, "FEDCBA98" },
+\tfmtTest{ "%x", b64, "ffffffffffffffff" },
+\tfmtTest{ "%b", 7, "111" },
+\tfmtTest{ "%b", b64, "1111111111111111111111111111111111111111111111111111111111111111" },
+\tfmtTest{ "%e", float64(1), "1.000000e+00" },
+\tfmtTest{ "%e", float64(1234.5678e3), "1.234568e+06" },
+\tfmtTest{ "%e", float64(1234.5678e-8), "1.234568e-05" },
+\tfmtTest{ "%e", float64(-7), "-7.000000e+00" },
+\tfmtTest{ "%e", float64(-1e-9), "-1.000000e-09" },
+\tfmtTest{ "%f", float64(1234.5678e3), "1234567.800000" },
+\tfmtTest{ "%f", float64(1234.5678e-8), "0.000012" },
+\tfmtTest{ "%f", float64(-7), "-7.000000" },
+\tfmtTest{ "%f", float64(-1e-9), "-0.000000" },
+\tfmtTest{ "%g", float64(1234.5678e3), "1.2345678e+06" },
+\tfmtTest{ "%g", float32(1234.5678e3), "1.2345678e+06" },
+\tfmtTest{ "%g", float64(1234.5678e-8), "1.2345678e-05" },
+\tfmtTest{ "%g", float64(-7), "-7" },
+\tfmtTest{ "%g", float64(-1e-9), "-1e-09", },
+\tfmtTest{ "%g", float32(-1e-9), "-1e-09" },
+\tfmtTest{ "%c", 'x', "x" },
+\tfmtTest{ "%c", 0xe4, "ä" },
+\tfmtTest{ "%c", 0x672c, "本" },
+\tfmtTest{ "%c", '日', "日" },
+\tfmtTest{ "%20.8d", 1234, " 00001234" },
+\tfmtTest{ "%20.8d", -1234, " -00001234" },
+\tfmtTest{ "%20d", 1234, " 1234" },
+\tfmtTest{ "%-20.8d", 1234, "00001234 " },
+\tfmtTest{ "%-20.8d", -1234, "-00001234 " },
+\tfmtTest{ "%.20b", 7, "00000000000000000111" },
+\tfmtTest{ "%20.5s", "qwertyuiop", " qwert" },
+\tfmtTest{ "%.5s", "qwertyuiop", "qwert" },
+\tfmtTest{ "%-20.5s", "qwertyuiop", "qwert " },
+\tfmtTest{ "%20c", 'x', " x" },
+\tfmtTest{ "%-20c", 'x', "x " },
+\tfmtTest{ "%20.6e", 1.2345e3, " 1.234500e+03" },
+\tfmtTest{ "%20.6e", 1.2345e-3, " 1.234500e-03" },
+\tfmtTest{ "%20e", 1.2345e3, " 1.234500e+03" },
+\tfmtTest{ "%20e", 1.2345e-3, " 1.234500e-03" },
+\tfmtTest{ "%20.8e", 1.2345e3, " 1.23450000e+03" },
+\tfmtTest{ "%20f", float64(1.23456789e3), " 1234.567890" },
+\tfmtTest{ "%20f", float64(1.23456789e-3), " 0.001235" },
+\tfmtTest{ "%20f", float64(12345678901.23456789), " 12345678901.234568" },
+\tfmtTest{ "%-20f", float64(1.23456789e3), "1234.567890 " },
+\tfmtTest{ "%20.8f", float64(1.23456789e3), " 1234.56789000" },
+\tfmtTest{ "%20.8f", float64(1.23456789e-3), " 0.00123457" },
+\tfmtTest{ "%g", float64(1.23456789e3), "1234.56789" },
+\tfmtTest{ "%g", float64(1.23456789e-3), "0.00123456789" },
+\tfmtTest{ "%g", float64(1.23456789e20), "1.23456789e+20" },
+\tfmtTest{ "%20e", sys.Inf(1), " +Inf" },
+\tfmtTest{ "%-20f", sys.Inf(-1), "-Inf " },
+\tfmtTest{ "%20g", sys.NaN(), " NaN" },
}\n \n export func TestSprintf(t *testing.T) {\n@@ -166,8 +166,8 @@ export func TestSprintf(t *testing.T) {\n \t}\n }\n \n-type FlagPrinter struct { }\n-func (*FlagPrinter) Format(f fmt.Formatter, c int) {\
+type flagPrinter struct { }\n+func (*flagPrinter) Format(f fmt.Formatter, c int) {\
\ts := "%";\n \tfor i := 0; i < 128; i++ {\n \t\tif f.Flag(i) {\n@@ -184,28 +184,28 @@ func (*FlagPrinter) Format(f fmt.Formatter, c int) {\n \tio.WriteString(f, "["+s+"]");\n }\n \n-type FlagTest struct {\
+type flagTest struct {\n \tin string;\n \tout string;\n }\n \n-var flagtests = []FlagTest {\
-\tFlagTest{ "%a", "[%a]" },\
-\tFlagTest{ "%-a", "[%-a]" },\
-\tFlagTest{ "%+a", "[%+a]" },\
-\tFlagTest{ "%#a", "[%#a]" },\
-\tFlagTest{ "% a", "[% a]" },\
-\tFlagTest{ "%0a", "[%0a]" },\
-\tFlagTest{ "%1.2a", "[%1.2a]" },\
-\tFlagTest{ "%-1.2a", "[%-1.2a]" },\
-\tFlagTest{ "%+1.2a", "[%+1.2a]" },\
-\tFlagTest{ "%-+1.2a", "[%+-1.2a]" },\
-\tFlagTest{ "%-+1.2abc", "[%+-1.2a]bc" },\
-\tFlagTest{ "%-1.2abc", "[%-1.2a]bc" },\
+var flagtests = []flagTest {\n+\tflagTest{ "%a", "[%a]" },\n+\tflagTest{ "%-a", "[%-a]" },\n+\tflagTest{ "%+a", "[%+a]" },\n+\tflagTest{ "%#a", "[%#a]" },\n+\tflagTest{ "% a", "[% a]" },\n+\tflagTest{ "%0a", "[%0a]" },\n+\tflagTest{ "%1.2a", "[%1.2a]" },\n+\tflagTest{ "%-1.2a", "[%-1.2a]" },\n+\tflagTest{ "%+1.2a", "[%+1.2a]" },\n+\tflagTest{ "%-+1.2a", "[%+-1.2a]" },\n+\tflagTest{ "%-+1.2abc", "[%+-1.2a]bc" },\n+\tflagTest{ "%-1.2abc", "[%-1.2a]bc" },\
}\n \n export func TestFlagParser(t *testing.T) {\n-\tvar flagprinter FlagPrinter;\
+\tvar flagprinter flagPrinter;\
\tfor i := 0; i < len(flagtests); i++ {\n \t\ttt := flagtests[i];\n \t\ts := fmt.Sprintf(tt.in, &flagprinter);\
コアとなるコードの解説
上記の変更箇所は、Go言語の命名規則における「可視性」の原則を徹底するために行われました。
src/lib/flag.go
の変更点
- 型名の変更:
BoolValue
,IntValue
,Int64Value
,UintValue
,Uint64Value
,StringValue
,Flags
といった構造体名が、それぞれboolValue
,intValue
,int64Value
,uintValue
,uint64Value
,stringValue
,allFlags
に変更されています。- 解説: Go言語では、型名が小文字で始まる場合、その型はパッケージ内部でのみ利用可能な非公開(unexported)な型となります。これにより、これらの「値」を扱う内部的な構造体が、
flag
パッケージの外部から直接参照されたり、依存されたりすることを防ぎます。これは、パッケージのAPIをクリーンに保ち、内部実装の変更が外部に影響を与えないようにするための重要なプラクタスです。Flags
からallFlags
への変更も同様の意図です。
- 解説: Go言語では、型名が小文字で始まる場合、その型はパッケージ内部でのみ利用可能な非公開(unexported)な型となります。これにより、これらの「値」を扱う内部的な構造体が、
- コンストラクタ関数名の変更:
NewBoolValue
,NewIntValue
などがnewBoolValue
,newIntValue
に変更されています。- 解説: 型名と同様に、コンストラクタ関数も小文字で始まる名前に変更することで、これらの関数がパッケージ内部でのみ使用されることを明確にしています。外部からフラグの値を設定する際には、
flag.Bool
,flag.Int
などの公開されたヘルパー関数を使用することが意図されています。
- 解説: 型名と同様に、コンストラクタ関数も小文字で始まる名前に変更することで、これらの関数がパッケージ内部でのみ使用されることを明確にしています。外部からフラグの値を設定する際には、
- メソッド名の変更:
BoolValue.Set
,BoolValue.Str
などがboolValue.set
,boolValue.str
に変更されています。また、Value
インターフェースのStr()
メソッドもstr()
に変更されています。- 解説: メソッド名も小文字で始まるように変更することで、これらのメソッドがパッケージ内部でのみ利用されることを示しています。特に
Value
インターフェースのstr()
メソッドが非公開になったことは、このインターフェースがパッケージの内部的な詳細であり、外部のコードがこのインターフェースを直接実装したり、そのメソッドを呼び出したりすることを想定していないことを意味します。
- 解説: メソッド名も小文字で始まるように変更することで、これらのメソッドがパッケージ内部でのみ利用されることを示しています。特に
- 内部関数名の変更:
Add
関数がadd
に変更されています。- 解説: この関数はフラグを内部的に追加するためのものであり、外部から直接呼び出されるべきではないため、小文字で始まる名前に変更されました。
src/lib/fmt/fmt_test.go
の変更点
- テスト用型名、定数名、変数名の変更:
FmtTest
,B32
,B64
,FlagPrinter
,FlagTest
といったテスト用の型、定数、変数が、それぞれfmtTest
,b32
,b64
,flagPrinter
,flagTest
のように小文字で始まる名前に変更されています。- 解説: テストコードもGoの命名規則に従うべきです。これらの識別子はテストファイル内でのみ使用される内部的な要素であるため、小文字で始めることでその可視性を適切に制限しています。これにより、テストコードの意図が明確になり、誤って本番コードからテスト用の識別子に依存してしまうような事態を防ぎます。
これらの変更は、Go言語のコードベース全体で一貫したスタイルと設計原則を適用し、コードの品質と保守性を高めるための初期段階における重要なリファクタリングの一環です。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/
- Go言語のEffective Go - Naming: https://go.dev/doc/effective_go#names
- Go言語のEffective Go - Exported names: https://go.dev/doc/effective_go#exported_names
- Go言語の
flag
パッケージ ドキュメント: https://pkg.go.dev/flag - Go言語の
fmt
パッケージ ドキュメント: https://pkg.go.dev/fmt
参考にした情報源リンク
- Go言語の公式ドキュメント (上記「関連リンク」に記載)
- Go言語のスタイルガイドや慣習に関する一般的な情報源 (例: Goコミュニティのブログ、技術記事など)
- GitHubのgolang/goリポジトリのコミット履歴