[インデックス 14136] ファイルの概要
このコミットは、Go言語の標準ライブラリであるfmt
パッケージのドキュメントを改善し、特に浮動小数点数の書式設定における幅(width)と精度(precision)の挙動、およびスキャン(scanning)機能における特定のフラグの未サポートについて、より詳細な説明を追加しています。これにより、開発者がfmt
パッケージをより正確に理解し、意図しない挙動を避けることができるようになります。
コミット
commit e171b97ee69b65400dbccb6ae2528747605e1505
Author: Rob Pike <r@golang.org>
Date: Fri Oct 12 16:16:55 2012 +1100
fmt: document some undocumented details
Better explanation of width for floating-point values.
Explain that scanning does not handle %#q etc.
Fixes #4202.
Fixes #4206.
R=golang-dev, adg, rsc, iant
CC=golang-dev
https://golang.org/cl/6620074
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e171b97ee69b65400dbccb6ae2528747605e1505
元コミット内容
fmt: document some undocumented details
Better explanation of width for floating-point values.
Explain that scanning does not handle %#q etc.
Fixes #4202.
Fixes #4206.
R=golang-dev, adg, rsc, iant
CC=golang-dev
https://golang.org/cl/6620074
変更の背景
このコミットは、Go言語のfmt
パッケージのドキュメントが、特定の書式設定(フォーマット)およびスキャン(パース)の挙動について十分に説明されていないという問題に対処するために行われました。具体的には、以下の2つのGitHub Issueを解決することを目的としています。
- Issue #4202:
fmt
: document %g precision: このIssueでは、%g
フォーマット指定子の精度に関するドキュメントが不足していることが指摘されていました。特に、%g
が浮動小数点数の表示において、指定された精度が「小数点以下の桁数」ではなく「全体の桁数」として扱われるという重要な違いが明確にされていませんでした。これにより、開発者が%g
の挙動を誤解し、期待しない出力になる可能性がありました。 - Issue #4206:
fmt
: document that Scan does not handle %#q etc.: このIssueでは、fmt.Scan
系の関数が、fmt.Printf
で使われるような特定のフラグ(例:#
や+
)をサポートしていないことがドキュメントに明記されていない点が問題視されていました。Printf
とScan
は対になる機能として認識されがちですが、すべてのフォーマットフラグが双方向でサポートされているわけではないため、この情報の欠如は混乱を招く可能性がありました。
これらのIssueは、fmt
パッケージのドキュメントの明確性と完全性を向上させる必要性を示しており、本コミットはその改善を目的としています。
前提知識の解説
このコミットの変更内容を理解するためには、Go言語のfmt
パッケージにおける以下の概念を理解しておく必要があります。
-
fmt
パッケージの役割:fmt
パッケージは、Go言語においてフォーマットされたI/O(入力/出力)を実装するための機能を提供します。これには、値を文字列に変換して出力する「フォーマット(Formatting)」機能(例:fmt.Printf
,fmt.Sprintf
)と、文字列から値をパースして読み取る「スキャン(Scanning)」機能(例:fmt.Scanf
,fmt.Sscanf
)があります。 -
フォーマット指定子(Format Verbs):
Printf
系の関数では、%d
(整数)、%f
(浮動小数点数)、%s
(文字列)、%v
(任意の型)などのフォーマット指定子を使用して、値の表示形式を制御します。 -
幅(Width)と精度(Precision):
- 幅(Width): フォーマットされた出力の最小幅を指定します。指定された幅よりも出力が短い場合、通常はスペースでパディングされます。例:
%6f
は、少なくとも6文字の幅で浮動小数点数を出力します。 - 精度(Precision): 浮動小数点数に対しては、通常、小数点以下の桁数を指定します。文字列に対しては、出力する最大文字数を指定します。例:
%.2f
は、小数点以下2桁で浮動小数点数を出力します。
- 幅(Width): フォーマットされた出力の最小幅を指定します。指定された幅よりも出力が短い場合、通常はスペースでパディングされます。例:
-
%e
,%f
,%g
フォーマット指定子: これらは浮動小数点数をフォーマットするための主要な指定子です。%e
/%E
: 科学表記(例:1.234560e+02
)%f
/%F
: 通常の浮動小数点表記(例:123.456000
)%g
/%G
: 値に応じて%e
または%f
のいずれか短い方を選択します。これは、数値の表現を最適化するために使用されます。
-
スキャン(Scanning):
Scan
系の関数は、入力文字列を解析し、指定されたフォーマットに基づいて値を抽出します。Printf
とは異なり、Scan
は入力の解析に特化しており、すべてのフォーマットフラグやオプションがPrintf
と同じように機能するわけではありません。 -
フォーマットフラグ(Format Flags):
Printf
系の関数では、フォーマット指定子の前に#
、+
、-
、0
などのフラグを付けることで、出力の挙動をさらに細かく制御できます。#
: 別の形式(例: 0xプレフィックス、引用符付き文字列)+
: 常に符号を表示
これらの概念を理解することで、コミットがfmt
パッケージのドキュメントにどのような改善をもたらしたのかを正確に把握できます。
技術的詳細
このコミットは、src/pkg/fmt/doc.go
ファイル内のドキュメント文字列を修正することで、fmt
パッケージの挙動に関する2つの重要な点を明確にしています。
-
浮動小数点数の幅と精度の説明の改善:
- 変更前は、数値の幅と精度に関する説明が簡潔で、特に
%g
の挙動について曖昧さがありました。 - 変更後、ドキュメントは「数値の場合、幅はフィールドの最小幅を設定し、精度は小数点以下の桁数を設定します」と明確に述べています。
- さらに重要なのは、
%g/%G
の場合には「全体の桁数」を設定するという例外が明記された点です。これは、%g
が他の浮動小数点フォーマット指定子(%e
,%f
)とは異なる精度解釈を持つことを強調しています。 - 具体例として、
123.45
に対して%6.2f
が123.45
と出力されるのに対し、%.4g
が123.5
と出力されることが示されています。これは、%g
が有効数字の数を制御することを示唆しています。 - また、
%e
と%f
のデフォルト精度が6であること、そして%g
のデフォルト精度が「値を一意に識別するために必要な最小桁数」であることも追記されました。これにより、デフォルトの挙動に関する混乱が解消されます。
- 変更前は、数値の幅と精度に関する説明が簡潔で、特に
-
スキャンにおけるフラグの未サポートの明記:
- 変更前は、
fmt.Scan
系の関数が特定のフォーマットフラグをサポートしていないことについて、明示的な記述がありませんでした。 - 変更後、スキャンに関するセクションに「
Flags # and + are not implemented.
」という行が追加されました。これは、Printf
で一般的に使用される#
(代替形式)と+
(常に符号を表示)のフラグが、スキャン時には機能しないことを明確に示しています。これにより、開発者がScan
関数でこれらのフラグを使用しようとして、期待しない結果になることを防ぎます。
- 変更前は、
これらの変更は、既存のコードの動作を変更するものではなく、あくまでドキュメントの正確性と網羅性を高めることを目的としています。これにより、fmt
パッケージのユーザーは、その挙動をより正確に予測し、適切なフォーマット指定子とフラグを選択できるようになります。
コアとなるコードの変更箇所
このコミットによる変更は、src/pkg/fmt/doc.go
ファイル内のドキュメント文字列に限定されています。
--- a/src/pkg/fmt/doc.go
+++ b/src/pkg/fmt/doc.go
@@ -56,9 +56,12 @@
character '*', causing their values to be obtained from the next
operand, which must be of type int.
- For numeric values, width sets the width of the field and precision
- sets the number of places after the decimal, if appropriate. For
- example, the format %6.2f prints 123.45.
+ For numeric values, width sets the minimum width of the field and
+ precision sets the number of places after the decimal, if appropriate,
+ except that for %g/%G it sets the total number of digits. For example,
+ given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
+ The default precision for %e and %f is 6; for %g it is the smallest
+ number of digits necessary to identify the value uniquely.
For strings, width is the minimum number of characters to output,
padding with spaces if necessary, and precision is the maximum
@@ -152,6 +155,7 @@
%T is not implemented
%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
%s and %v on strings scan a space-delimited token
+ Flags # and + are not implemented.
The familiar base-setting prefixes 0 (octal) and 0x
(hexadecimal) are accepted when scanning integers without a
コアとなるコードの解説
変更されたdoc.go
ファイルは、Go言語のfmt
パッケージの公式ドキュメントの一部です。このファイルは、Goのツールチェーンによって生成されるドキュメント(go doc fmt
コマンドやpkg.go.devなどで閲覧可能)の基となるコメントを含んでいます。
具体的な変更点は以下の通りです。
-
浮動小数点数の幅と精度に関する説明の拡張:
- 元の説明は「数値の場合、幅はフィールドの幅を設定し、精度は小数点以下の桁数を設定します。例えば、フォーマット
%6.2f
は123.45
を出力します。」と非常に簡潔でした。 - 新しい説明では、
width
が「最小幅」を設定すること、そして%g/%G
の場合にはprecision
が「全体の桁数」を設定するという重要な例外が追加されました。 123.45
を例に、%6.2f
が123.45
を出力する一方で、%.4g
が123.5
を出力するという具体的な例が追加され、%g
の挙動がより明確になりました。- さらに、
%e
と%f
のデフォルト精度が6であること、そして%g
のデフォルト精度が「値を一意に識別するために必要な最小桁数」であるという情報が追記され、デフォルトの挙動に関する詳細が提供されました。
- 元の説明は「数値の場合、幅はフィールドの幅を設定し、精度は小数点以下の桁数を設定します。例えば、フォーマット
-
スキャンにおけるフラグの未サポートの明記:
- スキャンに関するセクションに、
Flags # and + are not implemented.
という新しい行が追加されました。これは、fmt.Scan
系の関数が、Printf
で使われるような#
(代替形式)や+
(常に符号を表示)といったフラグをサポートしていないことを明示しています。これにより、開発者がスキャン時にこれらのフラグを使用しようとしてエラーや予期せぬ挙動に遭遇するのを防ぎます。
- スキャンに関するセクションに、
これらの変更は、fmt
パッケージのドキュメントの品質を向上させ、ユーザーがより正確かつ効率的にパッケージを使用できるようにすることを目的としています。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/e171b97ee69b65400dbccb6ae2528747605e1505
- Go Code Review: https://golang.org/cl/6620074
- Go Issue #4202:
fmt
: document %g precision: https://github.com/golang/go/issues/4202 - Go Issue #4206:
fmt
: document that Scan does not handle %#q etc.: https://github.com/golang/go/issues/4206
参考にした情報源リンク
- Go
fmt
パッケージ公式ドキュメント: https://pkg.go.dev/fmt - Go言語のフォーマット済みI/O (
fmt
パッケージ) の基本 - Go言語における浮動小数点数のフォーマット
- Go言語の
fmt.Scan
関数の使い方と注意点