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

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

このコミットは、Go言語の公式ドキュメントである Effective Go における変数名の命名規則に関する修正です。具体的には、変数名に ALL_CAPS (すべて大文字) を使用しないように、ドキュメント内のコード例が修正されています。

コミット

commit 3e2a8887532b87a339b8b15a0bb548bf9a6f7bf1
Author: Nigel Tao <nigeltao@golang.org>
Date:   Thu Nov 8 11:55:46 2012 +1100

    doc/effective_go: don't use ALL_CAPS for variable names.
    
    R=r, dsymonds
    CC=golang-dev
    https://golang.org/cl/6826070

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

https://github.com/golang/go/commit/3e2a8887532b87a339b8b15a0bb548bf9a6f7bf1

元コミット内容

doc/effective_go: don't use ALL_CAPS for variable names.

R=r, dsymonds
CC=golang-dev
https://golang.org/cl/6826070

変更の背景

この変更の背景には、Go言語における変数名の命名規則の標準化と、Effective Go ドキュメントの正確性の維持があります。Go言語では、変数名に ALL_CAPS を使用することは一般的ではありません。Goの命名規則では、エクスポートされる(パッケージ外から参照可能な)識別子は大文字で始まり、エクスポートされない(パッケージ内でのみ参照可能な)識別子は小文字で始まるという慣習があります。

ALL_CAPS は、他のプログラミング言語(特にC/C++やJavaなど)で定数を示すためによく使われる命名規則ですが、Goでは定数であっても通常は CamelCase (キャメルケース) または lowerCamelCase (ローワーキャメルケース) が推奨されます。特に、パッケージレベルの変数やグローバル変数であっても、それがエクスポートされない限りは小文字で始めるのがGoの慣習です。

Effective Go は、Go言語を効果的に書くためのベストプラクティスとイディオムを解説する公式ドキュメントであり、Goプログラマーにとって非常に重要な指針となります。このドキュメント内のコード例がGoの推奨する命名規則に沿っていない場合、読者に誤った慣習を広める可能性があります。そのため、ドキュメント内の ALL_CAPS で記述されていた変数名を、Goの慣習に沿った lowerCamelCase に修正する必要がありました。これにより、Effective Go がGo言語の正しいコーディングスタイルを反映し、読者がより良いGoコードを書くための手助けとなることが意図されています。

前提知識の解説

このコミットを理解するためには、以下のGo言語に関する前提知識が必要です。

  1. Go言語の命名規則:

    • エクスポートされた識別子: Goでは、識別子(変数、関数、型など)の名前が大文字で始まる場合、その識別子はパッケージ外から参照可能(エクスポートされる)になります。
    • エクスポートされない識別子: 識別子の名前が小文字で始まる場合、その識別子はパッケージ内でのみ参照可能(エクスポートされない)です。
    • 変数名: 一般的に、Goの変数名は lowerCamelCase (例: userName, httpRequest) が推奨されます。これは、ローカル変数、関数パラメータ、エクスポートされないパッケージレベルの変数に適用されます。
    • 定数名: 定数も通常は CamelCase (例: MaxConnections, DefaultTimeout) で記述されます。他の言語でよく見られる ALL_CAPS (例: MAX_CONNECTIONS) はGoでは一般的ではありません。
    • 略語: 略語(URL, HTTP, IDなど)は、単語の先頭が大文字になるように記述されます(例: serveHTTP, parseURL)。ただし、エクスポートされる場合は全体が大文字になります(例: HTTPClient, URLParser)。
  2. Effective Go:

    • Effective Go は、Go言語の公式ドキュメントの一部であり、Go言語を効果的かつイディオム的に記述するためのガイドラインを提供します。Goの設計思想、コーディングスタイル、一般的なパターン、およびベストプラクティスについて解説されており、Goプログラマーがより良いコードを書くための重要なリソースです。
    • このドキュメントは、Go言語の「精神」を理解し、Goの機能を最大限に活用するための方法を学ぶ上で不可欠です。
  3. os.Getenv:

    • os パッケージは、オペレーティングシステム機能へのプラットフォームに依存しないインターフェースを提供します。
    • os.Getenv(key string) string 関数は、指定された環境変数 key の値を返します。環境変数が設定されていない場合は空文字列を返します。
  4. log.Fatal:

    • log パッケージは、簡単なロギング機能を提供します。
    • log.Fatal 関数は、引数をフォーマットして標準エラー出力に出力し、os.Exit(1) を呼び出してプログラムを終了させます。これは、回復不可能なエラーが発生した場合によく使用されます。
  5. flag.StringVar:

    • flag パッケージは、コマンドラインフラグを解析するための機能を提供します。
    • flag.StringVar(p *string, name string, value string, usage string) 関数は、指定された name のコマンドラインフラグの値を p が指す文字列変数にバインドします。value はデフォルト値、usage はフラグの説明です。

これらの知識があることで、コミットがなぜ行われたのか、そしてその変更がGo言語の慣習にどのように適合するのかを深く理解することができます。

技術的詳細

このコミットは、doc/effective_go.html ファイル内のコード例における変数名の命名規則を修正しています。具体的には、環境変数を取得して初期化する部分と、その環境変数に基づいて初期設定を行う init 関数内のコードが対象です。

変更前は、HOME, USER, GOROOT といった環境変数を格納するGoの変数名が ALL_CAPS で記述されていました。これは、他の言語(特にC/C++やJava)で定数やマクロを示す際によく用いられる慣習ですが、Go言語の標準的な命名規則とは異なります。Goでは、エクスポートされないパッケージレベルの変数やローカル変数は lowerCamelCase で記述するのが慣習です。

このコミットでは、以下の変数名が変更されました。

  • HOME -> home
  • USER -> user
  • GOROOT -> goRoot

これらの変数は、os.Getenv を使って環境変数の値を取得し、プログラム内で使用されるものです。Goの慣習に従い、これらはパッケージ外にエクスポートされることを意図していないため、小文字で始まる lowerCamelCase に変更されました。

特に GOROOTgoRoot に変更されている点に注目です。Goの命名規則では、略語(GOROOT)が連続する場合、エクスポートされる識別子では GOROOT のように全体を大文字にしますが、エクスポートされない識別子では goRoot のように最初の単語の最初の文字のみを小文字にし、略語の残りの部分はそのまま大文字を維持することが推奨されます。これにより、可読性を保ちつつ、Goの命名規則に準拠しています。

この変更は、コードの機能には一切影響を与えません。これは純粋に、Effective Go ドキュメントがGo言語の推奨するコーディングスタイルを正確に反映するようにするための、ドキュメントの修正です。これにより、Effective Go を読む開発者が、Goのイディオムに沿った変数名の付け方を学ぶことができます。

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

--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -1745,9 +1745,9 @@ initializer can be a general expression computed at run time.
 </p>
 <pre>
 var (
-    HOME = os.Getenv("HOME")
-    USER = os.Getenv("USER")
-    GOROOT = os.Getenv("GOROOT")
+    home   = os.Getenv("HOME")
+    user   = os.Getenv("USER")
+    goRoot = os.Getenv("GOROOT")
 )
 </pre>
 
@@ -1770,17 +1770,17 @@ correctness of the program state before real execution begins.
 
 <pre>
 func init() {
-    if USER == "" {
+    if user == "" {
         log.Fatal("$USER not set")
     }
-    if HOME == "" {
-        HOME = "/home/" + USER
+    if home == "" {
+        home = "/home/" + user
     }
-    if GOROOT == "" {
-        GOROOT = HOME + "/go"
+    if goRoot == "" {
+        goRoot = home + "/go"
     }
-    // GOROOT may be overridden by --goroot flag on command line.
-    flag.StringVar(&amp;GOROOT, "goroot", GOROOT, "Go root directory")
+    // goRoot may be overridden by --goroot flag on command line.
+    flag.StringVar(&amp;goRoot, "goroot", goRoot, "Go root directory")
 }
 </pre>
 

コアとなるコードの解説

上記の diff は、doc/effective_go.html ファイル内の2つの主要なコードブロックに対する変更を示しています。

  1. 変数宣言ブロックの変更:

    -    HOME = os.Getenv("HOME")
    -    USER = os.Getenv("USER")
    -    GOROOT = os.Getenv("GOROOT")
    +    home   = os.Getenv("HOME")
    +    user   = os.Getenv("USER")
    +    goRoot = os.Getenv("GOROOT")
    

    この部分では、パッケージレベルで宣言されている変数 HOME, USER, GOROOT の名前がそれぞれ home, user, goRoot に変更されています。

    • var (...) 構文は、複数の変数をまとめて宣言するGoの慣用的な方法です。
    • os.Getenv("ENV_VAR_NAME") は、指定された環境変数の値を取得します。
    • 変更前は、これらの変数がすべて大文字(ALL_CAPS)で記述されていました。これは、Goの命名規則では通常、エクスポートされる識別子(パッケージ外から参照可能なもの)にのみ適用される慣習です。しかし、これらの変数はパッケージ内部でのみ使用されることを意図しているため、エクスポートする必要はありません。
    • 変更後、変数名は小文字で始まる lowerCamelCase になっています。これは、Goにおいてエクスポートされない変数に推奨される命名規則です。特に GOROOT から goRoot への変更は、略語を含む変数名のエクスポートされない形式のGoの慣習に沿っています。
  2. init 関数ブロックの変更:

    -    if USER == "" {
    +    if user == "" {
             log.Fatal("$USER not set")
         }
    -    if HOME == "" {
    -        HOME = "/home/" + USER
    +    if home == "" {
    +        home = "/home/" + user
         }
    -    if GOROOT == "" {
    -        GOROOT = HOME + "/go"
    +    if goRoot == "" {
    +        goRoot = home + "/go"
         }
    -    // GOROOT may be overridden by --goroot flag on command line.
    -    flag.StringVar(&amp;GOROOT, "goroot", GOROOT, "Go root directory")
    +    // goRoot may be overridden by --goroot flag on command line.
    +    flag.StringVar(&amp;goRoot, "goroot", goRoot, "Go root directory")
    

    この部分では、init 関数内の変数参照が、上記の変数名変更に合わせて更新されています。

    • init 関数は、パッケージが初期化される際に自動的に実行される特別な関数です。ここでは、環境変数の値に基づいて初期設定を行っています。
    • if USER == "" のような条件式や、HOME = "/home/" + USER のような代入式、そして flag.StringVar(&amp;GOROOT, ...) のような関数呼び出しにおいて、変更前の ALL_CAPS の変数名が使用されていました。
    • 変更後、これらの参照はすべて新しい lowerCamelCase の変数名(user, home, goRoot)に置き換えられています。
    • コメント行 // GOROOT may be overridden by --goroot flag on command line. も、変数名の変更に合わせて // goRoot may be overridden by --goroot flag on command line. に修正されています。

これらの変更は、Effective Go ドキュメント内のコード例が、Go言語の現在の推奨される命名規則と一致するようにするためのものです。これにより、ドキュメントの読者は、Goのイディオムに沿った正しいコーディングスタイルを学ぶことができます。機能的な変更は一切なく、純粋にドキュメントの正確性と一貫性を向上させるための修正です。

関連リンク

参考にした情報源リンク