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

[インデックス 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で使われるような特定のフラグ(例: #+)をサポートしていないことがドキュメントに明記されていない点が問題視されていました。PrintfScanは対になる機能として認識されがちですが、すべてのフォーマットフラグが双方向でサポートされているわけではないため、この情報の欠如は混乱を招く可能性がありました。

これらのIssueは、fmtパッケージのドキュメントの明確性と完全性を向上させる必要性を示しており、本コミットはその改善を目的としています。

前提知識の解説

このコミットの変更内容を理解するためには、Go言語のfmtパッケージにおける以下の概念を理解しておく必要があります。

  1. fmtパッケージの役割: fmtパッケージは、Go言語においてフォーマットされたI/O(入力/出力)を実装するための機能を提供します。これには、値を文字列に変換して出力する「フォーマット(Formatting)」機能(例: fmt.Printf, fmt.Sprintf)と、文字列から値をパースして読み取る「スキャン(Scanning)」機能(例: fmt.Scanf, fmt.Sscanf)があります。

  2. フォーマット指定子(Format Verbs): Printf系の関数では、%d(整数)、%f(浮動小数点数)、%s(文字列)、%v(任意の型)などのフォーマット指定子を使用して、値の表示形式を制御します。

  3. 幅(Width)と精度(Precision):

    • 幅(Width): フォーマットされた出力の最小幅を指定します。指定された幅よりも出力が短い場合、通常はスペースでパディングされます。例: %6fは、少なくとも6文字の幅で浮動小数点数を出力します。
    • 精度(Precision): 浮動小数点数に対しては、通常、小数点以下の桁数を指定します。文字列に対しては、出力する最大文字数を指定します。例: %.2fは、小数点以下2桁で浮動小数点数を出力します。
  4. %e, %f, %g フォーマット指定子: これらは浮動小数点数をフォーマットするための主要な指定子です。

    • %e / %E: 科学表記(例: 1.234560e+02
    • %f / %F: 通常の浮動小数点表記(例: 123.456000
    • %g / %G: 値に応じて%eまたは%fのいずれか短い方を選択します。これは、数値の表現を最適化するために使用されます。
  5. スキャン(Scanning): Scan系の関数は、入力文字列を解析し、指定されたフォーマットに基づいて値を抽出します。Printfとは異なり、Scanは入力の解析に特化しており、すべてのフォーマットフラグやオプションがPrintfと同じように機能するわけではありません。

  6. フォーマットフラグ(Format Flags): Printf系の関数では、フォーマット指定子の前に#+- (スペース)、0などのフラグを付けることで、出力の挙動をさらに細かく制御できます。

    • #: 別の形式(例: 0xプレフィックス、引用符付き文字列)
    • +: 常に符号を表示
    • : 負でない数値の前にスペースを追加

これらの概念を理解することで、コミットがfmtパッケージのドキュメントにどのような改善をもたらしたのかを正確に把握できます。

技術的詳細

このコミットは、src/pkg/fmt/doc.goファイル内のドキュメント文字列を修正することで、fmtパッケージの挙動に関する2つの重要な点を明確にしています。

  1. 浮動小数点数の幅と精度の説明の改善:

    • 変更前は、数値の幅と精度に関する説明が簡潔で、特に%gの挙動について曖昧さがありました。
    • 変更後、ドキュメントは「数値の場合、幅はフィールドの最小幅を設定し、精度は小数点以下の桁数を設定します」と明確に述べています。
    • さらに重要なのは、%g/%Gの場合には「全体の桁数」を設定するという例外が明記された点です。これは、%gが他の浮動小数点フォーマット指定子(%e, %f)とは異なる精度解釈を持つことを強調しています。
    • 具体例として、123.45に対して%6.2f123.45と出力されるのに対し、%.4g123.5と出力されることが示されています。これは、%gが有効数字の数を制御することを示唆しています。
    • また、%e%fのデフォルト精度が6であること、そして%gのデフォルト精度が「値を一意に識別するために必要な最小桁数」であることも追記されました。これにより、デフォルトの挙動に関する混乱が解消されます。
  2. スキャンにおけるフラグの未サポートの明記:

    • 変更前は、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などで閲覧可能)の基となるコメントを含んでいます。

具体的な変更点は以下の通りです。

  1. 浮動小数点数の幅と精度に関する説明の拡張:

    • 元の説明は「数値の場合、幅はフィールドの幅を設定し、精度は小数点以下の桁数を設定します。例えば、フォーマット%6.2f123.45を出力します。」と非常に簡潔でした。
    • 新しい説明では、widthが「最小幅」を設定すること、そして%g/%Gの場合にはprecisionが「全体の桁数」を設定するという重要な例外が追加されました。
    • 123.45を例に、%6.2f123.45を出力する一方で、%.4g123.5を出力するという具体的な例が追加され、%gの挙動がより明確になりました。
    • さらに、%e%fのデフォルト精度が6であること、そして%gのデフォルト精度が「値を一意に識別するために必要な最小桁数」であるという情報が追記され、デフォルトの挙動に関する詳細が提供されました。
  2. スキャンにおけるフラグの未サポートの明記:

    • スキャンに関するセクションに、Flags # and + are not implemented.という新しい行が追加されました。これは、fmt.Scan系の関数が、Printfで使われるような#(代替形式)や+(常に符号を表示)といったフラグをサポートしていないことを明示しています。これにより、開発者がスキャン時にこれらのフラグを使用しようとしてエラーや予期せぬ挙動に遭遇するのを防ぎます。

これらの変更は、fmtパッケージのドキュメントの品質を向上させ、ユーザーがより正確かつ効率的にパッケージを使用できるようにすることを目的としています。

関連リンク

参考にした情報源リンク

  • Go fmtパッケージ公式ドキュメント: https://pkg.go.dev/fmt
  • Go言語のフォーマット済みI/O (fmtパッケージ) の基本
  • Go言語における浮動小数点数のフォーマット
  • Go言語のfmt.Scan関数の使い方と注意点