Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11979] ファイルの概要

このコミットは、Go言語の仕様書(doc/go_spec.html)における構造体(struct)の比較に関する記述を修正するものです。具体的には、構造体の比較において、ブランク識別子(blank identifier)で宣言されたフィールドが比較の対象外となることを明確にする変更が加えられています。

コミット

commit 3908467b1f5e4f591616081088145a833cf77655
Author: Robert Griesemer <gri@golang.org>
Date:   Thu Feb 16 14:13:17 2012 -0800

    go spec: struct comparison only compares non-blank fields
    
    Fixes #3031.
    
    R=golang-dev, rsc, r, iant
    CC=golang-dev
    https://golang.org/cl/5676054

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/3908467b1f5e4f591616081088145a833cf77655

元コミット内容

このコミットの元の内容は、Go言語の仕様書において、構造体の比較に関する記述を修正することです。具体的には、「構造体の値は、その対応するフィールドが等しい場合に等しい」という既存の記述に対し、「その対応する非ブランクフィールドが等しい場合に等しい」という修正を加えています。これにより、ブランク識別子(_)で宣言されたフィールドは構造体の比較において無視されることが明示されます。

変更の背景

この変更は、Go言語のIssue #3031("spec: struct comparison should ignore blank fields")を修正するために行われました。このIssueでは、構造体の比較において、ブランク識別子で宣言されたフィールドが比較の対象となるべきではないという点が議論されていました。

Go言語において、ブランク識別子(_)は、変数を宣言するもののその値を意図的に破棄する場合や、インポートしたパッケージの副作用のみを利用する場合などに使用されます。構造体のフィールドにブランク識別子を使用することは稀ですが、例えば、特定のインターフェースを満たすためにダミーのフィールドを置く場合や、将来の拡張のためにプレースホルダーとしてフィールドを予約する場合などに考えられます。

もしブランクフィールドが構造体の比較に含まれてしまうと、そのフィールドの値が比較結果に影響を与えてしまい、意図しない挙動を引き起こす可能性があります。例えば、ブランクフィールドが比較可能な型(例: int)であった場合、その値が偶然一致するかしないかで構造体全体の比較結果が変わってしまうことになります。これは、ブランクフィールドが「意味を持たない」というブランク識別子の本来の意図に反します。

このコミットは、このような潜在的な混乱や誤解を解消し、Go言語の設計思想と一貫性を持たせるために、仕様書を明確化することを目的としています。

前提知識の解説

Go言語の構造体(Struct)

Go言語における構造体は、異なる型のフィールド(プロパティ)をまとめた複合データ型です。C言語の構造体やJava/Pythonのクラスのインスタンス変数に似ています。

type Person struct {
    Name string
    Age  int
}

Go言語の比較可能性(Comparability)

Go言語では、特定の型の値は比較可能(comparable)であり、== 演算子や != 演算子を使って等価性をチェックできます。比較可能な型には、ブール型、数値型、文字列型、ポインタ型、チャネル型、インターフェース型、配列型、そしてすべてのフィールドが比較可能な構造体型があります。

ブランク識別子(Blank Identifier: _

Go言語のブランク識別子(_)は、値を破棄するために使用される特別な識別子です。例えば、関数の複数の戻り値のうち一部だけが必要な場合や、インポートしたパッケージの副作用だけを利用したい場合などに使われます。

// 複数の戻り値のうち、エラーだけをチェックしたい場合
_, err := someFunction()
if err != nil {
    // エラー処理
}

// パッケージの初期化関数(init)だけを実行したい場合
import _ "net/http/pprof"

構造体のフィールド名としてブランク識別子を使用することも可能です。

type MyStruct struct {
    Field1 int
    _      string // このフィールドはブランク識別子
    Field3 bool
}

この場合、_ で宣言されたフィールドは、その値にアクセスしたり、代入したりすることはできません。これは、そのフィールドが「意味を持たない」ことを示唆しています。

技術的詳細

このコミットの技術的な詳細は、Go言語の仕様書(doc/go_spec.html)の「Comparison operators」セクションにおける構造体の比較に関する記述の変更に集約されます。

変更前は、構造体の比較について以下のように記述されていました。

Struct values are comparable if all the fields are comparable. Two struct values are equal if their corresponding fields are equal.

これは、「すべてのフィールドが比較可能であれば、構造体の値は比較可能である。2つの構造体の値は、その対応するフィールドが等しい場合に等しい」という意味です。この記述では、ブランク識別子で宣言されたフィールドが比較に含まれるかどうかが不明確でした。

変更後は、以下のように修正されました。

Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.

この修正により、「2つの構造体の値は、その対応する非ブランクフィールドが等しい場合に等しい」という点が明確にされました。ここで「non-blank」という言葉が追加され、さらにブランク識別子に関するセクションへのリンク(<a href="#Blank_identifier">blank</a>)が追加されています。

この変更は、Goコンパイラやランタイムの実際の挙動を反映し、仕様書をより正確にするものです。Go言語の内部実装では、ブランクフィールドは通常、メモリレイアウトには含まれるものの、その値がプログラムのロジックに影響を与えることはありません。したがって、比較においてもその値を考慮しないのが自然な挙動となります。

この仕様の明確化により、開発者は構造体の比較を行う際に、ブランクフィールドの存在を意識する必要がなくなり、より直感的で安全なコードを書くことができるようになります。

コアとなるコードの変更箇所

変更は doc/go_spec.html ファイルの以下の部分です。

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
  	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of February 14, 2012"
+	"Subtitle": "Version of February 16, 2012"
 }-->
 
 <!--
@@ -3058,8 +3058,9 @@ These terms and the result of the comparisons are defined as follows:\n 	</li>\n \n \t<li>
-\tStruct values are comparable if all the fields are comparable.\n-\tTwo struct values are equal if their corresponding fields are equal.\n+\tStruct values are comparable if all their fields are comparable.\n+\tTwo struct values are equal if their corresponding\n+\tnon-<a href=\"#Blank_identifier\">blank</a> fields are equal.\n \t</li>
 \t
 \t<li>

具体的には、以下の行が変更されています。

  1. 日付の更新: 仕様書のバージョン日付が「February 14, 2012」から「February 16, 2012」に更新されています。これは、仕様書の内容が更新されたことを示す一般的な変更です。
  2. 構造体比較の記述修正:
    • - Two struct values are equal if their corresponding fields are equal.
    • + Two struct values are equal if their corresponding
    • + non-<a href="#Blank_identifier">blank</a> fields are equal.

この変更により、構造体の比較に関する説明文に「non-blank」という修飾語と、ブランク識別子へのハイパーリンクが追加されています。

コアとなるコードの解説

変更されたHTMLスニペットは、Go言語の公式仕様書の一部です。このセクションは、Go言語における比較演算子(==!=)がどのように機能するかを定義しています。

特に重要なのは、<li> タグ内の構造体比較に関する記述です。

元の記述: Two struct values are equal if their corresponding fields are equal. (2つの構造体の値は、その対応するフィールドが等しい場合に等しい。)

修正後の記述: Two struct values are equal if their corresponding non-<a href="#Blank_identifier">blank</a> fields are equal. (2つの構造体の値は、その対応する非ブランクフィールドが等しい場合に等しい。)

この変更は、Go言語のセマンティクス(意味論)における重要なニュアンスを明確にしています。ブランク識別子で宣言されたフィールドは、その値がプログラムのロジックにおいて意味を持たないため、構造体の等価性チェックにおいても無視されるべきであるという設計意図を反映しています。

HTMLの <a> タグは、同じドキュメント内の「Blank_identifier」というアンカー(#Blank_identifier)へのリンクを作成しています。これにより、読者は「ブランク識別子」が何を意味するのか、その場で詳細な説明を参照できるようになっています。これは、仕様書の可読性と理解度を高めるための良いプラクティスです。

関連リンク

参考にした情報源リンク

  • Go言語のIssue #3031の議論内容
  • Go言語の公式ドキュメント(特に仕様書)
  • Go言語におけるブランク識別子の一般的な用法に関する情報
  • Go言語における構造体の比較に関する一般的な情報
  • Go言語のコミット履歴と関連するコードレビュー(Gerrit CL 5676054)

[インデックス 11979] ファイルの概要

このコミットは、Go言語の仕様書(doc/go_spec.html)における構造体(struct)の比較に関する記述を修正するものです。具体的には、構造体の比較において、ブランク識別子(blank identifier)で宣言されたフィールドが比較の対象外となることを明確にする変更が加えられています。

コミット

commit 3908467b1f5e4f591616081088145a833cf77655
Author: Robert Griesemer <gri@golang.org>
Date:   Thu Feb 16 14:13:17 2012 -0800

    go spec: struct comparison only compares non-blank fields
    
    Fixes #3031.
    
    R=golang-dev, rsc, r, iant
    CC=golang-dev
    https://golang.org/cl/5676054

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/3908467b1f5e4f591616081088145a833cf77655

元コミット内容

このコミットの元の内容は、Go言語の仕様書において、構造体の比較に関する記述を修正することです。具体的には、「構造体の値は、その対応するフィールドが等しい場合に等しい」という既存の記述に対し、「その対応する非ブランクフィールドが等しい場合に等しい」という修正を加えています。これにより、ブランク識別子(_)で宣言されたフィールドは構造体の比較において無視されることが明示されます。

変更の背景

この変更は、Go言語のIssue #3031("spec: struct comparison should ignore blank fields")を修正するために行われました。このIssueでは、構造体の比較において、ブランク識別子で宣言されたフィールドが比較の対象となるべきではないという点が議論されていました。

Go言語において、ブランク識別子(_)は、変数を宣言するもののその値を意図的に破棄する場合や、インポートしたパッケージの副作用のみを利用する場合などに使用されます。構造体のフィールドにブランク識別子を使用することは稀ですが、例えば、特定のインターフェースを満たすためにダミーのフィールドを置く場合や、将来の拡張のためにプレースホルダーとしてフィールドを予約する場合などに考えられます。

もしブランクフィールドが構造体の比較に含まれてしまうと、そのフィールドの値が比較結果に影響を与えてしまい、意図しない挙動を引き起こす可能性があります。例えば、ブランクフィールドが比較可能な型(例: int)であった場合、その値が偶然一致するかしないかで構造体全体の比較結果が変わってしまうことになります。これは、ブランクフィールドが「意味を持たない」というブランク識別子の本来の意図に反します。

このコミットは、このような潜在的な混乱や誤解を解消し、Go言語の設計思想と一貫性を持たせるために、仕様書を明確化することを目的としています。

前提知識の解説

Go言語の構造体(Struct)

Go言語における構造体は、異なる型のフィールド(プロパティ)をまとめた複合データ型です。C言語の構造体やJava/Pythonのクラスのインスタンス変数に似ています。

type Person struct {
    Name string
    Age  int
}

Go言語の比較可能性(Comparability)

Go言語では、特定の型の値は比較可能(comparable)であり、== 演算子や != 演算子を使って等価性をチェックできます。比較可能な型には、ブール型、数値型、文字列型、ポインタ型、チャネル型、インターフェース型、配列型、そしてすべてのフィールドが比較可能な構造体型があります。

ブランク識別子(Blank Identifier: _

Go言語のブランク識別子(_)は、値を破棄するために使用される特別な識別子です。例えば、関数の複数の戻り値のうち一部だけが必要な場合や、インポートしたパッケージの副作用だけを利用したい場合などに使われます。

// 複数の戻り値のうち、エラーだけをチェックしたい場合
_, err := someFunction()
if err != nil {
    // エラー処理
}

// パッケージの初期化関数(init)だけを実行したい場合
import _ "net/http/pprof"

構造体のフィールド名としてブランク識別子を使用することも可能です。

type MyStruct struct {
    Field1 int
    _      string // このフィールドはブランク識別子
    Field3 bool
}

この場合、_ で宣言されたフィールドは、その値にアクセスしたり、代入したりすることはできません。これは、そのフィールドが「意味を持たない」ことを示唆しています。

技術的詳細

このコミットの技術的な詳細は、Go言語の仕様書(doc/go_spec.html)の「Comparison operators」セクションにおける構造体の比較に関する記述の変更に集約されます。

変更前は、構造体の比較について以下のように記述されていました。

Struct values are comparable if all the fields are comparable. Two struct values are equal if their corresponding fields are equal.

これは、「すべてのフィールドが比較可能であれば、構造体の値は比較可能である。2つの構造体の値は、その対応するフィールドが等しい場合に等しい」という意味です。この記述では、ブランク識別子で宣言されたフィールドが比較に含まれるかどうかが不明確でした。

変更後は、以下のように修正されました。

Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.

この修正により、「2つの構造体の値は、その対応する非ブランクフィールドが等しい場合に等しい」という点が明確にされました。ここで「non-blank」という言葉が追加され、さらにブランク識別子に関するセクションへのリンク(<a href="#Blank_identifier">blank</a>)が追加されています。

この変更は、Goコンパイラやランタイムの実際の挙動を反映し、仕様書をより正確にするものです。Go言語の内部実装では、ブランクフィールドは通常、メモリレイアウトには含まれるものの、その値がプログラムのロジックに影響を与えることはありません。したがって、比較においてもその値を考慮しないのが自然な挙動となります。

この仕様の明確化により、開発者は構造体の比較を行う際に、ブランクフィールドの存在を意識する必要がなくなり、より直感的で安全なコードを書くことができるようになります。

コアとなるコードの変更箇所

変更は doc/go_spec.html ファイルの以下の部分です。

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
  	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of February 14, 2012"
+	"Subtitle": "Version of February 16, 2012"
 }-->
 
 <!--
@@ -3058,8 +3058,9 @@ These terms and the result of the comparisons are defined as follows:\n 	</li>\n 
 \t<li>
-\tStruct values are comparable if all the fields are comparable.\n-\tTwo struct values are equal if their corresponding fields are equal.\n+\tStruct values are comparable if all their fields are comparable.\n+\tTwo struct values are equal if their corresponding\n+\tnon-<a href=\"#Blank_identifier\">blank</a> fields are equal.\n \t</li>
 \t
 \t<li>

具体的には、以下の行が変更されています。

  1. 日付の更新: 仕様書のバージョン日付が「February 14, 2012」から「February 16, 2012」に更新されています。これは、仕様書の内容が更新されたことを示す一般的な変更です。
  2. 構造体比較の記述修正:
    • - Two struct values are equal if their corresponding fields are equal.
    • + Two struct values are equal if their corresponding
    • + non-<a href="#Blank_identifier">blank</a> fields are equal.

この変更により、構造体の比較に関する説明文に「non-blank」という修飾語と、ブランク識別子へのハイパーリンクが追加されています。

コアとなるコードの解説

変更されたHTMLスニペットは、Go言語の公式仕様書の一部です。このセクションは、Go言語における比較演算子(==!=)がどのように機能するかを定義しています。

特に重要なのは、<li> タグ内の構造体比較に関する記述です。

元の記述: Two struct values are equal if their corresponding fields are equal. (2つの構造体の値は、その対応するフィールドが等しい場合に等しい。)

修正後の記述: Two struct values are equal if their corresponding non-<a href="#Blank_identifier">blank</a> fields are equal. (2つの構造体の値は、その対応する非ブランクフィールドが等しい場合に等しい。)

この変更は、Go言語のセマンティクス(意味論)における重要なニュアンスを明確にしています。ブランク識別子で宣言されたフィールドは、その値がプログラムのロジックにおいて意味を持たないため、構造体の等価性チェックにおいても無視されるべきであるという設計意図を反映しています。

HTMLの <a> タグは、同じドキュメント内の「Blank_identifier」というアンカー(#Blank_identifier)へのリンクを作成しています。これにより、読者は「ブランク識別子」が何を意味するのか、その場で詳細な説明を参照できるようになっています。これは、仕様書の可読性と理解度を高めるための良いプラクティスです。

関連リンク

参考にした情報源リンク

  • Go言語のIssue #3031の議論内容
  • Go言語の公式ドキュメント(特に仕様書)
  • Go言語におけるブランク識別子の一般的な用法に関する情報
  • Go言語における構造体の比較に関する一般的な情報
  • Go言語のコミット履歴と関連するコードレビュー(Gerrit CL 5676054)