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

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

このコミットは、Go言語の標準ライブラリであるflagパッケージ内のsrc/pkg/flag/flag.goファイルに対するスタイル更新です。具体的には、flagパッケージの使用例を示すコメント内のコードスニペットが、よりGo言語の慣用的なスタイルに修正されています。

コミット

flag: update style.

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

https://github.com/golang/go/commit/b20163e9e48fe300112de18f75cfa77c04968f2a

元コミット内容

commit b20163e9e48fe300112de18f75cfa77c04968f2a
Author: David Symonds <dsymonds@golang.org>
Date:   Tue Apr 17 16:37:35 2012 +1000

    flag: update style.
    
    R=golang-dev, r, r
    CC=golang-dev
    https://golang.org/cl/6051044
---
 src/pkg/flag/flag.go | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/pkg/flag/flag.go b/src/pkg/flag/flag.go
index c28d0e7207..f0842a18a2 100644
--- a/src/pkg/flag/flag.go
+++ b/src/pkg/flag/flag.go
@@ -7,9 +7,11 @@
  
  	Usage:
  
-	Define flags using flag.String(), Bool(), Int(), etc. Example:
+	Define flags using flag.String(), Bool(), Int(), etc.
+
+	This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
  		import "flag"
-		var ip *int = flag.Int("flagname", 1234, "help message for flagname")
+		var ip = flag.Int("flagname", 1234, "help message for flagname")
  	If you like, you can bind the flag to a variable using the Var() functions.
  		var flagvar int
  		func init() {
@@ -26,8 +28,8 @@
  
  	Flags may then be used directly. If you\'re using the flags themselves,
  	they are all pointers; if you bind to variables, they\'re values.
-		fmt.Println("ip has value ", *ip);
-		fmt.Println("flagvar has value ", flagvar);
+		fmt.Println("ip has value ", *ip)
+		fmt.Println("flagvar has value ", flagvar)
  
  	After parsing, the arguments after the flag are available as the
  	slice flag.Args() or individually as flag.Arg(i).

変更の背景

このコミットは、Go言語のコードスタイルガイドラインの進化と、より慣用的なGoコードの記述を促進するために行われました。特に、Go言語では型推論が強力であり、冗長な型宣言を避けることが推奨されます。また、Goの文法ではほとんどの場合、文の終わりにセミコロンを明示的に記述する必要がなく、コンパイラが自動的に挿入します。このコミットは、これらのGo言語の基本的なスタイル原則を、標準ライブラリのドキュメント内のコード例に反映させることを目的としています。これにより、Go言語の初心者や既存のユーザーが、より推奨されるコーディングスタイルを学ぶことができます。

前提知識の解説

Go言語のflagパッケージ

flagパッケージは、コマンドライン引数を解析するためのGo言語の標準パッケージです。プログラムの起動時にユーザーが指定するオプション(フラグ)を定義し、その値をプログラム内で利用できるようにします。例えば、-port 8080のような引数を解析し、portという名前のフラグに8080という値を割り当てることができます。

Go言語の型推論

Go言語は静的型付け言語ですが、変数の初期化時に型を明示的に指定しない場合でも、コンパイラが初期値から変数の型を自動的に推論する機能を持っています。例えば、var x = 10と記述すると、コンパイラはxint型と推論します。これにより、コードの記述量を減らし、可読性を向上させることができます。

Go言語におけるセミコロン

Go言語の文法では、C言語やJavaのような他の言語とは異なり、ほとんどの文の終わりにセミコロンを明示的に記述する必要がありません。Goのコンパイラは、改行に基づいて自動的にセミコロンを挿入するルール(Automatic Semicolon Insertion)を持っています。これにより、コードがより簡潔になり、セミコロンの付け忘れによるエラーが減少します。ただし、1行に複数の文を記述する場合は、それらをセミコロンで区切る必要があります。

ポインタ

Go言語におけるポインタは、変数のメモリアドレスを保持する変数です。*演算子を使ってポインタが指すアドレスに格納されている値にアクセス(デリファレンス)できます。flag.Intのような関数は、フラグの値を格納する*int型のポインタを返します。これは、フラグの値が解析後に更新されるため、その更新された値にアクセスするためにポインタが必要となるためです。

技術的詳細

このコミットで行われたスタイル変更は、Go言語の慣用的な記述方法に沿ったものです。

  1. var ip *int = flag.Int(...) から var ip = flag.Int(...) への変更:

    • 変更前は、ip変数が*int型であることを明示的に宣言していました。
    • flag.Int関数は*int型の値を返します。Goの型推論機能により、flag.Intの戻り値からipの型が*intであるとコンパイラが自動的に推論できます。
    • したがって、var ip = flag.Int(...)と記述することで、冗長な型宣言を省略し、より簡潔でGoらしいコードになります。これは、GoのEffective GoやGo Code Review Commentsで推奨されるスタイルです。
  2. fmt.Println(...) の行末のセミコロンの削除:

    • 変更前は、fmt.Printlnの呼び出しの行末にセミコロンが明示的に記述されていました。
    • Go言語では、ほとんどの場合、文の終わりにセミコロンを記述する必要がありません。コンパイラが自動的に挿入するためです。
    • この変更は、Goの自動セミコロン挿入のルールに則り、不要なセミコロンを削除することで、コードの見た目をすっきりとさせ、Goの標準的なスタイルに合わせるものです。

これらの変更は、コードの機能には影響を与えませんが、Go言語のコミュニティで広く受け入れられているコーディング規約に準拠することで、コードの可読性と保守性を向上させます。

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

--- a/src/pkg/flag/flag.go
+++ b/src/pkg/flag/flag.go
@@ -7,9 +7,11 @@
  
  	Usage:
  
-	Define flags using flag.String(), Bool(), Int(), etc. Example:
+	Define flags using flag.String(), Bool(), Int(), etc.
+
+	This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
  		import "flag"
-		var ip *int = flag.Int("flagname", 1234, "help message for flagname")
+		var ip = flag.Int("flagname", 1234, "help message for flagname")
  	If you like, you can bind the flag to a variable using the Var() functions.
  		var flagvar int
  		func init() {
@@ -26,8 +28,8 @@
  
  	Flags may then be used directly. If you\'re using the flags themselves,
  	they are all pointers; if you bind to variables, they\'re values.
-		fmt.Println("ip has value ", *ip);
-		fmt.Println("flagvar has value ", flagvar);
+		fmt.Println("ip has value ", *ip)
+		fmt.Println("flagvar has value ", flagvar)
  
  	After parsing, the arguments after the flag are available as the
  	slice flag.Args() or individually as flag.Arg(i).

コアとなるコードの解説

変更されたコードは、src/pkg/flag/flag.goファイル内のコメントブロックに記述されたGo言語のコード例です。

  1. var ip *int = flag.Int("flagname", 1234, "help message for flagname") の変更:

    • この行は、flagパッケージを使って整数型のコマンドラインフラグを定義する例です。
    • 変更前は、ip変数が*int型であることを明示的に宣言していました。
    • 変更後は、var ip = ...という形式になり、flag.Intが返す*int型からipの型が自動的に推論されるようになりました。これはGo言語の型推論を活用した、より簡潔で推奨される記述方法です。
  2. fmt.Println("ip has value ", *ip); および fmt.Println("flagvar has value ", flagvar); の変更:

    • これらの行は、定義したフラグの値を出力する例です。
    • 変更前は、各行の終わりにセミコロンが明示的に記述されていました。
    • 変更後は、これらのセミコロンが削除されました。Go言語では、ほとんどの文の終わりにセミコロンを明示的に記述する必要がないため、これはGoの自動セミコロン挿入のルールに合わせた、より慣用的なスタイルです。

これらの変更は、flagパッケージの機能自体には影響を与えませんが、Go言語の標準ライブラリのドキュメントが、最新かつ推奨されるGoのコーディングスタイルを反映するように更新されたことを示しています。

関連リンク

参考にした情報源リンク