[インデックス 17607] ファイルの概要
このコミットは、Go言語の標準ライブラリ sort
パッケージ内の example_interface_test.go
ファイルに対する変更です。具体的には、sort.Interface
の使用例をより簡潔にし、パッケージレベルに移動させることを目的としています。
コミット
commit 49eeef5927b37a96d1bb733197cff7ea974aad2c
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Sep 16 13:02:01 2013 +1000
sort: move example to package level and simplify further
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/13634044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/49eeef5927b37a96d1bb733197cff7ea974aad2c
元コミット内容
sort: move example to package level and simplify further
このコミットメッセージは、sort
パッケージの例をパッケージレベルに移動させ、さらに簡素化することを示しています。
変更の背景
Go言語の標準ライブラリの例は、その機能の利用方法を示す上で非常に重要です。このコミットの背景には、sort
パッケージの Interface
の使用例をより分かりやすく、かつGoのイディオムに沿った形に改善するという意図があります。
元のコードでは、ExampleInterface()
という関数名が使われていましたが、Goの Example
関数は、パッケージレベルで Example
という名前で定義することで、go doc
コマンドや godoc
ツールによって自動的にドキュメントとして抽出され、実行可能なテストとしても機能します。これにより、ユーザーはコードの動作を簡単に確認できるようになります。
また、[]*Person
のようにポインタのスライスを使用していた部分を []Person
のように値のスライスに変更することで、コードの記述がより簡潔になり、不要なポインタのデリファレンスを避けることができます。これは、Goにおいて構造体を値として扱うことが一般的であるという設計思想にも合致しています。
前提知識の解説
このコミットを理解するためには、以下のGo言語の概念と sort
パッケージの知識が必要です。
-
Go言語の
sort
パッケージ:sort
パッケージは、Goのスライスをソートするための機能を提供します。- ソートの対象となる型は、
sort.Interface
インターフェースを実装する必要があります。 sort.Interface
は以下の3つのメソッドを定義しています。Len() int
: ソート対象の要素数を返します。Swap(i, j int)
: インデックスi
とj
の要素を入れ替えます。Less(i, j int) bool
: インデックスi
の要素がインデックスj
の要素よりも小さい(ソート順で前になる)場合にtrue
を返します。
sort.Sort(data Interface)
関数にsort.Interface
を実装した型を渡すことで、ソートが実行されます。
-
Go言語の
Example
関数:- Goのテストファイル(
_test.go
で終わるファイル)内にExample
というプレフィックスを持つ関数を定義すると、それは特別な意味を持ちます。 func Example()
: パッケージ全体の例として扱われます。func ExampleF()
: 関数F
の例として扱われます。func ExampleT_M()
: 型T
のメソッドM
の例として扱われます。- これらの
Example
関数は、go doc
コマンドでドキュメントとして表示されるだけでなく、go test
コマンドで実行可能なテストとしても機能します。// Output:
コメントに記述された出力と実際の出力が一致するかどうかを検証します。これにより、ドキュメントとコードの整合性が保たれます。
- Goのテストファイル(
-
ポインタと値:
- Goでは、変数を値として渡すか、ポインタとして渡すかを選択できます。
- 値として渡すと、元のデータのコピーが渡されます。
- ポインタとして渡すと、元のデータのメモリアドレスが渡され、関数内で元のデータを変更できます。
- スライスの場合、
[]T
は型T
の値のスライスを意味し、[]*T
は型T
へのポインタのスライスを意味します。 - 一般的に、Goでは小さな構造体や、変更が頻繁に発生しない構造体は値として扱うことが推奨されます。これにより、ガベージコレクションの負荷を軽減し、コードを簡潔に保つことができます。
技術的詳細
このコミットは、sort
パッケージの example_interface_test.go
ファイルにおける ExampleInterface
関数の変更に焦点を当てています。
変更の核心は以下の2点です。
-
ExampleInterface()
からExample()
への関数名変更:- Goの
Example
関数の命名規則に従い、ExampleInterface()
という特定のインターフェースの例を示す関数名を、パッケージ全体の例を示すExample()
に変更しました。これにより、go doc sort
を実行した際に、この例がsort
パッケージの主要な使用例として表示されるようになります。 - また、
go test
実行時にこの例が自動的にテストされ、出力が期待通りであることを検証します。
- Goの
-
ByAge []*Person
からByAge []Person
への変更、およびpeople
スライスの初期化の簡素化:- 元のコードでは、
ByAge
型が[]*Person
(Person構造体へのポインタのスライス) として定義されており、people
スライスも[]*Person
として初期化されていました。 - 変更後、
ByAge
型は[]Person
(Person構造体の値のスライス) となり、people
スライスも[]Person
として初期化されます。 - これに伴い、
people
スライスの初期化も&Person{Name: "Bob", Age: 31}
のようなポインタの取得ではなく、{"Bob", 31}
のような構造体リテラルによる値の直接初期化に簡素化されています。これは、Person
構造体がエクスポートされていないフィールド(Name
とAge
)を持つため、フィールド名を省略した順序での初期化が可能です。 - この変更により、
sort.Interface
を実装するByAge
型がポインタではなく値のスライスを扱うようになり、コードがより直接的で読みやすくなります。Goでは、構造体を値として扱うことが一般的であり、特にソートのような操作では、要素のコピーが発生してもパフォーマンス上の大きな問題がない限り、値のスライスを使用する方が簡潔です。
- 元のコードでは、
これらの変更は、Goのイディオムに沿ったコードの記述を促進し、ドキュメンテーションとテストの自動化を最大限に活用するためのものです。
コアとなるコードの変更箇所
--- a/src/pkg/sort/example_interface_test.go
+++ b/src/pkg/sort/example_interface_test.go
@@ -20,18 +20,18 @@ func (p Person) String() string {
// ByAge implements sort.Interface for []Person based on
// the Age field.
-type ByAge []*Person
+type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
-func ExampleInterface() {
- people := []*Person{
- &Person{Name: "Bob", Age: 31},\
- &Person{Name: "John", Age: 42},\
- &Person{Name: "Michael", Age: 17},\
- &Person{Name: "Jenny", Age: 26},\
+func Example() {
+ people := []Person{
+ {"Bob", 31},\
+ {"John", 42},\
+ {"Michael", 17},\
+ {"Jenny", 26},\
}
fmt.Println(people)
コアとなるコードの解説
上記の差分から、以下の変更点とその意図が読み取れます。
-
type ByAge []*Person
からtype ByAge []Person
への変更:- これは
ByAge
型がソートする対象を、Person
構造体へのポインタのスライスから、Person
構造体の値のスライスへと変更したことを意味します。 - これにより、
Less
メソッド内でa[i].Age
のように直接フィールドにアクセスできるようになり、ポインタのデリファレンス((*a[i]).Age
のような記述)が不要になります。コードがより簡潔になります。
- これは
-
func ExampleInterface()
からfunc Example()
への変更:- Goの
Example
関数の命名規則に従い、関数名をExample
に変更しました。 - この変更により、この関数は
sort
パッケージ全体の例として認識され、go doc sort
コマンドで表示されるドキュメントに自動的に含まれるようになります。 - また、
go test
実行時にこの例がテストとして実行され、その出力が// Output:
コメントに記述された内容と一致するかどうかが検証されます。
- Goの
-
people := []*Person{...}
からpeople := []Person{...}
への変更:people
スライスの型がPerson
構造体のポインタのスライスから、Person
構造体の値のスライスに変更されました。これはByAge
型の変更と整合性を保つためのものです。
-
&Person{Name: "Bob", Age: 31}
から{"Bob", 31}
への初期化の簡素化:Person
構造体の初期化において、ポインタを取得する&
演算子とフィールド名を省略し、{"Bob", 31}
のように直接値を指定する形式に変更されました。- これは、
Person
構造体のフィールドがエクスポートされていない(小文字で始まる)ため、構造体リテラルでフィールド名を省略して順序通りに値を指定できるGoの機能を利用したものです。これにより、コードがさらに簡潔になります。
これらの変更は、Goのイディオムに沿ったコードの記述を促進し、sort
パッケージの例をより分かりやすく、かつGoのツールチェーン(go doc
, go test
)と連携して機能するように改善することを目的としています。
関連リンク
- Go言語の
sort
パッケージのドキュメント: https://pkg.go.dev/sort - Go言語の
testing
パッケージのExample
関数のドキュメント: https://pkg.go.dev/testing#hdr-Examples
参考にした情報源リンク
- https://golang.org/cl/13634044 (Goのコードレビューシステムにおけるこのコミットの変更リスト)
- Go言語の公式ドキュメントおよびGoコミュニティの慣習に関する一般的な知識。
- Go言語におけるポインタと値の扱いに関する一般的なプログラミング知識。
- Go言語の構造体リテラルに関する知識。# [インデックス 17607] ファイルの概要
このコミットは、Go言語の標準ライブラリ sort
パッケージ内の example_interface_test.go
ファイルに対する変更です。具体的には、sort.Interface
の使用例をより簡潔にし、パッケージレベルに移動させることを目的としています。
コミット
commit 49eeef5927b37a96d1bb733197cff7ea974aad2c
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Sep 16 13:02:01 2013 +1000
sort: move example to package level and simplify further
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/13634044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/49eeef5927b37a96d1bb733197cff7ea974aad2c
元コミット内容
sort: move example to package level and simplify further
このコミットメッセージは、sort
パッケージの例をパッケージレベルに移動させ、さらに簡素化することを示しています。
変更の背景
Go言語の標準ライブラリの例は、その機能の利用方法を示す上で非常に重要です。このコミットの背景には、sort
パッケージの Interface
の使用例をより分かりやすく、かつGoのイディオムに沿った形に改善するという意図があります。
元のコードでは、ExampleInterface()
という関数名が使われていましたが、Goの Example
関数は、パッケージレベルで Example
という名前で定義することで、go doc
コマンドや godoc
ツールによって自動的にドキュメントとして抽出され、実行可能なテストとしても機能します。これにより、ユーザーはコードの動作を簡単に確認できるようになります。
また、[]*Person
のようにポインタのスライスを使用していた部分を []Person
のように値のスライスに変更することで、コードの記述がより簡潔になり、不要なポインタのデリファレンスを避けることができます。これは、Goにおいて構造体を値として扱うことが一般的であるという設計思想にも合致しています。
前提知識の解説
このコミットを理解するためには、以下のGo言語の概念と sort
パッケージの知識が必要です。
-
Go言語の
sort
パッケージ:sort
パッケージは、Goのスライスをソートするための機能を提供します。- ソートの対象となる型は、
sort.Interface
インターフェースを実装する必要があります。 sort.Interface
は以下の3つのメソッドを定義しています。Len() int
: ソート対象の要素数を返します。Swap(i, j int)
: インデックスi
とj
の要素を入れ替えます。Less(i, j int) bool
: インデックスi
の要素がインデックスj
の要素よりも小さい(ソート順で前になる)場合にtrue
を返します。
sort.Sort(data Interface)
関数にsort.Interface
を実装した型を渡すことで、ソートが実行されます。
-
Go言語の
Example
関数:- Goのテストファイル(
_test.go
で終わるファイル)内にExample
というプレフィックスを持つ関数を定義すると、それは特別な意味を持ちます。 func Example()
: パッケージ全体の例として扱われます。func ExampleF()
: 関数F
の例として扱われます。func ExampleT_M()
: 型T
のメソッドM
の例として扱われます。- これらの
Example
関数は、go doc
コマンドでドキュメントとして表示されるだけでなく、go test
コマンドで実行可能なテストとしても機能します。// Output:
コメントに記述された出力と実際の出力が一致するかどうかを検証します。これにより、ドキュメントとコードの整合性が保たれます。
- Goのテストファイル(
-
ポインタと値:
- Goでは、変数を値として渡すか、ポインタとして渡すかを選択できます。
- 値として渡すと、元のデータのコピーが渡されます。
- ポインタとして渡すと、元のデータのメモリアドレスが渡され、関数内で元のデータを変更できます。
- スライスの場合、
[]T
は型T
の値のスライスを意味し、[]*T
は型T
へのポインタのスライスを意味します。 - 一般的に、Goでは小さな構造体や、変更が頻繁に発生しない構造体は値として扱うことが推奨されます。これにより、ガベージコレクションの負荷を軽減し、コードを簡潔に保つことができます。
技術的詳細
このコミットは、sort
パッケージの example_interface_test.go
ファイルにおける ExampleInterface
関数の変更に焦点を当てています。
変更の核心は以下の2点です。
-
ExampleInterface()
からExample()
への関数名変更:- Goの
Example
関数の命名規則に従い、ExampleInterface()
という特定のインターフェースの例を示す関数名を、パッケージ全体の例を示すExample()
に変更しました。これにより、go doc sort
を実行した際に、この例がsort
パッケージの主要な使用例として表示されるようになります。 - また、
go test
実行時にこの例が自動的にテストされ、出力が期待通りであることを検証します。
- Goの
-
ByAge []*Person
からByAge []Person
への変更、およびpeople
スライスの初期化の簡素化:- 元のコードでは、
ByAge
型が[]*Person
(Person構造体へのポインタのスライス) として定義されており、people
スライスも[]*Person
として初期化されていました。 - 変更後、
ByAge
型は[]Person
(Person構造体の値のスライス) となり、people
スライスも[]Person
として初期化されます。 - これに伴い、
people
スライスの初期化も&Person{Name: "Bob", Age: 31}
のようなポインタの取得ではなく、{"Bob", 31}
のような構造体リテラルによる値の直接初期化に簡素化されています。これは、Person
構造体がエクスポートされていないフィールド(Name
とAge
)を持つため、フィールド名を省略した順序での初期化が可能です。 - この変更により、
sort.Interface
を実装するByAge
型がポインタではなく値のスライスを扱うようになり、コードがより直接的で読みやすくなります。Goでは、構造体を値として扱うことが一般的であり、特にソートのような操作では、要素のコピーが発生してもパフォーマンス上の大きな問題がない限り、値のスライスを使用する方が簡潔です。
- 元のコードでは、
これらの変更は、Goのイディオムに沿ったコードの記述を促進し、ドキュメンテーションとテストの自動化を最大限に活用するためのものです。
コアとなるコードの変更箇所
--- a/src/pkg/sort/example_interface_test.go
+++ b/src/pkg/sort/example_interface_test.go
@@ -20,18 +20,18 @@ func (p Person) String() string {
// ByAge implements sort.Interface for []Person based on
// the Age field.
-type ByAge []*Person
+type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
-func ExampleInterface() {\
- people := []*Person{\
- &Person{Name: "Bob", Age: 31},\
- &Person{Name: "John", Age: 42},\
- &Person{Name: "Michael", Age: 17},\
- &Person{Name: "Jenny", Age: 26},\
+func Example() {\
+ people := []Person{\
+ {"Bob", 31},\
+ {"John", 42},\
+ {"Michael", 17},\
+ {"Jenny", 26},\
}
fmt.Println(people)
コアとなるコードの解説
上記の差分から、以下の変更点とその意図が読み取れます。
-
type ByAge []*Person
からtype ByAge []Person
への変更:- これは
ByAge
型がソートする対象を、Person
構造体へのポインタのスライスから、Person
構造体の値のスライスへと変更したことを意味します。 - これにより、
Less
メソッド内でa[i].Age
のように直接フィールドにアクセスできるようになり、ポインタのデリファレンス((*a[i]).Age
のような記述)が不要になります。コードがより簡潔になります。
- これは
-
func ExampleInterface()
からfunc Example()
への変更:- Goの
Example
関数の命名規則に従い、関数名をExample
に変更しました。 - この変更により、この関数は
sort
パッケージ全体の例として認識され、go doc sort
コマンドで表示されるドキュメントに自動的に含まれるようになります。 - また、
go test
実行時にこの例がテストとして実行され、その出力が// Output:
コメントに記述された内容と一致するかどうかが検証されます。
- Goの
-
people := []*Person{...}
からpeople := []Person{...}
への変更:people
スライスの型がPerson
構造体のポインタのスライスから、Person
構造体の値のスライスに変更されました。これはByAge
型の変更と整合性を保つためのものです。
-
&Person{Name: "Bob", Age: 31}
から{"Bob", 31}
への初期化の簡素化:Person
構造体の初期化において、ポインタを取得する&
演算子とフィールド名を省略し、{"Bob", 31}
のように直接値を指定する形式に変更されました。- これは、
Person
構造体のフィールドがエクスポートされていない(小文字で始まる)ため、構造体リテラルでフィールド名を省略して順序通りに値を指定できるGoの機能を利用したものです。これにより、コードがさらに簡潔になります。
これらの変更は、Goのイディオムに沿ったコードの記述を促進し、sort
パッケージの例をより分かりやすく、かつGoのツールチェーン(go doc
, go test
)と連携して機能するように改善することを目的としています。
関連リンク
- Go言語の
sort
パッケージのドキュメント: https://pkg.go.dev/sort - Go言語の
testing
パッケージのExample
関数のドキュメント: https://pkg.go.dev/testing#hdr-Examples
参考にした情報源リンク
- https://golang.org/cl/13634044 (Goのコードレビューシステムにおけるこのコミットの変更リスト)
- Go言語の公式ドキュメントおよびGoコミュニティの慣習に関する一般的な知識。
- Go言語におけるポインタと値の扱いに関する一般的なプログラミング知識。
- Go言語の構造体リテラルに関する知識。