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

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

このコミットは、Go言語の公式FAQドキュメントである doc/go_faq.html に対する複数の小さな修正と調整を目的としています。具体的には、Goのインターフェースの重要性に関する記述の追加、スライスと構造体の等価性に関する説明の明確化、メソッドレシーバ(値とポインタ)の挙動に関する詳細な説明、GOMAXPROCS 環境変数の設定方法の補足、go test コマンドへの修正、テスト関連ドキュメントへのリンク更新、Goバイナリのサイズに関する記述の更新、およびベンチマークに関する記述の修正が含まれています。

コミット

commit 5cff1903ea07f0f7087be72379dded4a987ca589
Author: Rob Pike <r@golang.org>
Date:   Mon Feb 20 12:42:50 2012 +1100

    FAQ: many small fixes and adjustments
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5685048

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

https://github.com/golang/go/commit/5cff1903ea07f0f7087be72379dded4a987ca589

元コミット内容

FAQ: many small fixes and adjustments

変更の背景

このコミットは、Go言語のFAQドキュメント doc/go_faq.html の内容を最新の状態に保ち、読者にとってより正確で理解しやすいものにするために行われました。特に、Go 1.0のリリースが近づいていた時期であり、Go 1.0での変更点(例えば、構造体と配列の等価性の定義)や、Goの設計思想(インターフェースの重要性、メソッドレシーバの挙動)に関するよくある疑問に対して、より明確な説明を提供することが目的でした。また、コマンド名(gotestからgo testへ)やドキュメントリンクの更新など、時間の経過とともに発生した情報の陳腐化に対応することも含まれています。

前提知識の解説

このコミットの変更内容を理解するためには、以下のGo言語の概念に関する知識が役立ちます。

  • Goのインターフェース (Interfaces): Goのインターフェースは、メソッドのシグネチャの集合を定義する型です。型がインターフェースのすべてのメソッドを実装していれば、そのインターフェースを満たしていると見なされます。これにより、柔軟な設計とポリモーフィズムが実現されます。コミットでは、io.Writer の例を挙げ、インターフェースがプログラムの構造に与える影響の深さが強調されています。
  • 等価性 (Equality) と比較: Goでは、異なる型間で等価性の定義が異なります。
    • 構造体 (Structs): Go 1以降、構造体はフィールドがすべて比較可能であれば、フィールドごとの値の比較によって等価性が定義されます。
    • 配列 (Arrays): 配列も要素が比較可能であれば、要素ごとの値の比較によって等価性が定義されます。
    • スライス (Slices): スライスは参照型であり、その等価性は定義されていません。つまり、スライスの内容が同じであっても、== 演算子で比較すると常に false になります(nil スライス同士の比較を除く)。これは、スライスが基盤となる配列の一部を参照しているため、浅い比較と深い比較の複雑さが絡むためです。
  • メソッドレシーバ (Method Receivers): Goのメソッドは、レシーバと呼ばれる特別な引数を持ちます。レシーバは値型 (T) またはポインタ型 (*T) のいずれかです。
    • 値レシーバ (Value Receiver): メソッドが値レシーバを持つ場合、メソッドはレシーバのコピーを受け取ります。メソッド内でレシーバのフィールドを変更しても、元の値には影響しません。
    • ポインタレシーバ (Pointer Receiver): メソッドがポインタレシーバを持つ場合、メソッドはレシーバのアドレスを受け取ります。メソッド内でレシーバのフィールドを変更すると、元の値も変更されます。 このコミットでは、値レシーバのメソッド内でレシーバを変更しても、呼び出し元にその変更が反映されないという重要な点が強調されています。
  • GOMAXPROCS: GOMAXPROCS はGoランタイムが同時に実行できるOSスレッドの最大数を制御する環境変数です。この値を設定することで、Goプログラムが利用するCPUコア数を調整できます。Go 1.5以降はデフォルトで利用可能なCPUコア数に設定されるため、手動で設定する必要はほとんどありませんが、古いGoのバージョンや特定のパフォーマンスチューニングの際には重要でした。
  • go test コマンド: Goの標準テストツールであり、Goパッケージ内のテスト関数(Testで始まる関数)を実行するために使用されます。
  • testing パッケージ: Goの標準ライブラリに含まれるパッケージで、ユニットテストの記述をサポートします。

技術的詳細

このコミットで行われた技術的な調整は、主にGo FAQドキュメントの正確性と明瞭性を向上させることに焦点を当てています。

  1. インターフェースの重要性の強調: io.Writer の例に続き、「Goのインターフェースは、プログラムの構造に深い影響を与える」という文が追加されました。これは、Goのインターフェースが単なる抽象化のメカニズムではなく、Goらしい設計パターン(例えば、小さなインターフェースの組み合わせ)を形成する上で中心的な役割を果たすことを示唆しています。
  2. 等価性の説明の修正と明確化:
    • 以前の記述では「構造体と配列の等価性が何を意味すべきか」という曖昧な表現がありましたが、これを「スライスの等価性が何を意味すべきか」に修正し、スライスの等価性の定義が依然として課題であることを明確にしました。
    • Go 1での変更点として、「Go 1では、以前のリリースとは異なり、構造体と配列の等価性が定義されており、これらの型をマップのキーとして使用できる」と明記されました。これにより、Go 1で導入された重要な変更が強調され、読者の誤解を防ぎます。
  3. メソッドレシーバの挙動に関する補足:
    • 値レシーバのメソッド内でレシーバの値を変更しても、呼び出し元にその変更が反映されないという重要な注意点が追加されました。これは、Goの「値渡し」のセマンティクスを理解する上で非常に重要なポイントです。コンパイラが値のアドレスを取得してメソッドに渡すことができたとしても、メソッドが値を変更した場合、その変更は呼び出し元には伝播しないという点が強調されています。
  4. GOMAXPROCS の設定方法の具体化:
    • 単に「GOMAXPROCS を設定する必要がある」という記述から、「GOMAXPROCS シェル環境変数を設定するか、runtime パッケージの同名の関数を使用する必要がある」という具体的な指示に修正されました。これにより、ユーザーはGOMAXPROCSを設定するための2つの主要な方法を明確に理解できます。
  5. テストコマンドの更新とドキュメントリンクの拡充:
    • 古いテストコマンド gotest が、現在の標準である go test に修正されました。
    • テストに関する詳細情報へのリンクが拡充され、How to Write Go Code ドキュメントに加えて、testing パッケージのドキュメントと go test サブコマンドのドキュメントへのリンクが追加されました。これにより、ユーザーはテストに関するより包括的な情報を参照できるようになりました。
  6. Goバイナリサイズに関する記述の更新:
    • Goの「hello, world」プログラムのバイナリサイズが、以前の「約1.1 MB」から「約1.3 MB」に更新されました。また、「いくつかの努力でGoバイナリのサイズを削減できる」という将来的な可能性に関する記述が削除されました。これは、当時のGo 1.0の現実的なバイナリサイズを反映し、将来の最適化に関する約束を避けるための変更と考えられます。
  7. ベンチマークに関する記述の修正:
    • ベンチマークの参照パスが test/bench から test/bench/shootout に変更され、より具体的なベンチマークスイートを指すようになりました。
    • Goのパフォーマンスに関する記述に、「言語とツールが発展するにつれて、多くのプログラムのパフォーマンスが大幅に改善された」という文が追加されました。これは、Goのパフォーマンスが継続的に向上していることを示唆しています。

これらの変更は、Go FAQがGo言語の進化に合わせて常に最新かつ正確な情報を提供するようにするための継続的な努力の一部です。

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

doc/go_faq.html ファイルの以下の箇所が変更されました。

--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -485,6 +485,7 @@
 or how the <code>image</code> packages generate compressed
 image files.  All these ideas stem from a single interface
 (<code>io.Writer</code>) representing a single method
 (<code>Write</code>).  And that's only scratching the surface.
+Go's interfaces have a profound influence on how programs are structured.
 </p>
 
 <p>
@@ -840,12 +841,12 @@
 there are multiple considerations involving shallow vs. deep comparison, pointer
 value comparison, how to deal with recursive types, and so on.
 We may revisit this issue&mdash;and implementing equality for slices
 will not invalidate any existing programs&mdash;but without a clear idea of what
-equality of structs and arrays should mean, it was simpler to leave it out for now.
+equality of slices should mean, it was simpler to leave it out for now.
 </p>
 
 <p>
-In Go 1, equality is defined for structs and arrays, so such
-types can be used as map keys, but slices still do not have a definition of equality.
+In Go 1, unlike prior releases, equality is defined for structs and arrays, so such
+types can be used as map keys. Slices still do not have a definition of equality, though.
 </p>
 
 <h3 id="references">
@@ -941,7 +942,7 @@
 func (s MyStruct)  valueMethod()   { } // method on value
 For programmers unaccustomed to pointers, the distinction between these
 two examples can be confusing, but the situation is actually very simple.
 When defining a method on a type, the receiver (<code>s</code> in the above
-example) behaves exactly as if it were an argument to the method.
+examples) behaves exactly as if it were an argument to the method.
 Whether to define the receiver as a value or as a pointer is the same
 question, then, as whether a function argument should be a value or
 a pointer.
@@ -1082,15 +1083,15 @@
 See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code
 Why doesn't my multi-goroutine program use multiple CPUs?</h3>
 
 <p>
-You must set <code>GOMAXPROCS</code> to allow the
+You must set the <code>GOMAXPROCS</code> shell environment variable
+or use the similarly-named <a href="/pkg/runtime/#GOMAXPROCS"><code>function</code></a>
+of the runtime package to allow the
 run-time support to utilize more than one OS thread. 
 </p>
 
 <p>
 Programs that perform parallel computation should benefit from an increase in
-<code>GOMAXPROCS</code>. (See the <a
-href="http://golang.org/pkg/runtime/#GOMAXPROCS"><code>runtime</code> package's
-documentation</a>.)
+<code>GOMAXPROCS</code>.
 </p>
 
 <h3 id="Why_GOMAXPROCS">
@@ -1148,7 +1149,10 @@
 there is no useful way for a method call to obtain a pointer.
 </p>
 
 <p>
-If not for this restriction, this code:
+Even in cases where the compiler could take the address of a value
+to pass to the method, if the method modifies the value the changes
+will be lost in the caller.
+As a common example, this code:
 </p>
 
 <pre>
@@ -1174,7 +1178,7 @@
 func main() {
     done := make(chan bool)
 
-    values := []string{ "a", "b", "c" }
+    values := []string{"a", "b", "c"}
     for _, v := range values {
         go func() {
             fmt.Println(v)
@@ -1268,18 +1272,21 @@
 func TestFoo(t *testing.T) {
 </pre>
 
 <p>
-Run <code>gotest</code> in that directory.
+Run <code>go test</code> in that directory.
 That script finds the <code>Test</code> functions,
 builds a test binary, and runs it.
 </p>
 
-<p>See the <a href="/doc/code.html">How to Write Go Code</a> document for more details.</p>
+<p>See the <a href="/doc/code.html">How to Write Go Code</a> document,
+the <a href="/pkg/testing/"><code>testing</code></a> package
+and the <a href="/cmd/go/#Test_packages"><code>go test</code></a> subcommand for more details.
+</p>
 
 <h3 id="testing_framework">
 Where is my favorite helper function for testing?</h3>
 
 <p>
-Go's standard <code>testing</code> package makes it easy to write unit tests, but it lacks
+Go's standard <a href="/pkg/testing/"><code>testing</code></a> package makes it easy to write unit tests, but it lacks
 features provided in other language's testing frameworks such as assertion functions.
 An <a href="#assertions">earlier section</a> of this document explained why Go
 doesn't have assertions, and
@@ -1371,9 +1378,9 @@
 type checks, reflection, and even panic-time stack traces.
 
 <p>
 A trivial C "hello, world" program compiled and linked statically using gcc
-on Linux is around 750 kB.  An equivalent Go program is around 1.1 MB, but
-that includes more powerful run-time support.  We believe that with some effort
-the size of Go binaries can be reduced.
+on Linux is around 750 kB.  An equivalent Go program using <code>fmt.Printf</code>
+is around 1.3 MB, but
+that includes more powerful run-time support.
 </p>
 
 <h3 id="unused_variables_and_imports">
@@ -1438,7 +1445,7 @@
 <p>
 One of Go's design goals is to approach the performance of C for comparable
 programs, yet on some benchmarks it does quite poorly, including several 
-in <a href="/test/bench/">test/bench</a>. The slowest depend on libraries 
+in <a href="/test/bench/shootout/">test/bench/shootout</a>. The slowest depend on libraries 
 for which versions of comparable performance are not available in Go. 
 For instance, <a href="/test/bench/shootout/pidigits.go">pidigits.go</a>
 depends on a multi-precision math package, and the C
@@ -1467,7 +1474,10 @@
 garbage can have a huge effect.)
 </p>
 
 <p>
-In any case, Go can often be very competitive. See the blog post about
+In any case, Go can often be very competitive.
+There has been significant improvement in the performance of many programs
+as the language and tools have developed.
+See the blog post about
 <a href="http://blog.golang.org/2011/06/profiling-go-programs.html">profiling
 Go programs</a> for an informative example.
 

コアとなるコードの解説

  • インターフェースの記述追加:
    • Go's interfaces have a profound influence on how programs are structured.
    • io.Writer のようなシンプルなインターフェースが、いかに強力な抽象化と柔軟な設計を可能にするかを補足し、Goのインターフェースが単なる機能提供以上の、プログラム構造全体に影響を与える存在であることを強調しています。
  • 等価性の説明の修正:
    • equality of structs and arrays should meanequality of slices should mean に変更。これは、Go 1で構造体と配列の等価性が定義された一方で、スライスの等価性は依然として複雑な問題であることを明確にするための修正です。
    • In Go 1, unlike prior releases, equality is defined for structs and arrays, so such types can be used as map keys. Slices still do not have a definition of equality, though.
    • Go 1での重要な変更点として、構造体と配列がマップのキーとして使用できるようになったことを明記し、以前のバージョンとの違いを強調しています。スライスが依然として等価性を持たないことも再確認しています。
  • メソッドレシーバの例の修正:
    • exampleexamples に変更。これは単なる文法的な修正です。
  • GOMAXPROCS の説明の具体化:
    • You must set the GOMAXPROCS shell environment variable or use the similarly-named <a href="/pkg/runtime/#GOMAXPROCS"><code>function</code></a> of the runtime package to allow the run-time support to utilize more than one OS thread.
    • GOMAXPROCS を設定する方法として、環境変数と runtime パッケージの関数の両方を明記し、より具体的な指示を提供しています。
    • runtime パッケージへの冗長なリンクを削除しました。
  • 値レシーバの挙動に関する補足:
    • Even in cases where the compiler could take the address of a value to pass to the method, if the method modifies the value the changes will be lost in the caller. As a common example, this code:
    • 値レシーバのメソッドがレシーバのコピーを受け取るため、メソッド内で値を変更しても呼び出し元には影響しないという、Goの重要なセマンティクスを明確に説明しています。これは、Goのポインタと値の挙動に関するよくある誤解を解消するためのものです。
  • スライス初期化のフォーマット修正:
    • values := []string{ "a", "b", "c" }values := []string{"a", "b", "c"} に変更。これは単なるコードスタイルの調整です。
  • テストコマンドの更新とリンクの拡充:
    • gotestgo test に変更。これは、Goのテストコマンドの正式名称への更新です。
    • テストに関する詳細情報へのリンクとして、How to Write Go Code に加えて、testing パッケージと go test サブコマンドのドキュメントへのリンクを追加し、より包括的な情報源を提供しています。
    • testing パッケージへのリンクを追加。
  • Goバイナリサイズに関する記述の更新:
    • An equivalent Go program using <code>fmt.Printf</code> is around 1.3 MB, but that includes more powerful run-time support.
    • Goの「hello, world」プログラムのバイナリサイズを現実的な値に更新し、将来的なサイズ削減に関する約束を削除しました。
  • ベンチマークパスの修正とパフォーマンスに関する記述の追加:
    • test/bench/test/bench/shootout/ に変更し、より具体的なベンチマークスイートを指すようにしました。
    • There has been significant improvement in the performance of many programs as the language and tools have developed.
    • Goのパフォーマンスが継続的に改善されていることを示す文を追加し、読者に最新の状況を伝えています。

関連リンク

参考にした情報源リンク