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

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

このコミットは、Go言語の標準ライブラリであるfmtパッケージのドキュメンテーションを改善することを目的としています。具体的には、Printf系のフォーマット関数における「幅 (width)」と「精度 (precision)」の指定方法に関する説明を、より明確で理解しやすいものに修正しています。これにより、開発者がfmtパッケージをより正確に利用できるようになります。

コミット

  • コミットハッシュ: 78992439f4f909ff21b9283b7a307840783afb15
  • 作者: Rob Pike r@golang.org
  • コミット日時: 2014年3月12日(水) 22:00:48 +1100
  • コミットメッセージ:
    fmt: improve documentation for width and precision
    Fixes #7048.
    
    LGTM=dominik.honnef
    R=golang-codereviews, dominik.honnef
    CC=golang-codereviews
    https://golang.org/cl/74280044
    

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

https://github.com/golang/go/commit/78992439f4f909ff21b9283b7a307840783afb15

元コミット内容

fmt: improve documentation for width and precision
Fixes #7048.

LGTM=dominik.honnef
R=golang-codereviews, dominik.honnef
CC=golang-codereviews
https://golang.org/cl/74280044

変更の背景

このコミットは、Go言語のfmtパッケージにおけるフォーマット指定子(特に幅と精度)に関するドキュメンテーションが、既存のユーザーにとって十分に明確でなかったという問題(Issue #7048)に対応するために行われました。

fmtパッケージは、C言語のprintfに似た書式指定文字列を用いた出力機能を提供しますが、Go独自のセマンティクス(特にUnicodeコードポイント単位での幅/精度計算)が存在します。以前のドキュメンテーションでは、幅と精度の指定方法や、それらが異なるデータ型(数値、文字列、浮動小数点数)にどのように適用されるかについての説明が不足しており、ユーザーが意図した通りのフォーマットを実現する上で混乱を招く可能性がありました。

このコミットは、具体的な例を提示し、各指定子の挙動をより詳細に説明することで、ドキュメンテーションの品質を向上させ、ユーザーの理解を深めることを目的としています。

前提知識の解説

Go言語のfmtパッケージ

fmtパッケージは、Go言語における基本的なI/Oフォーマット機能を提供します。fmt.Printffmt.Sprintffmt.Fprintfなどの関数を通じて、C言語のprintfに似た書式指定文字列を使用して、様々なデータ型を整形して出力することができます。

Printf-style フォーマット

Printf-styleフォーマットは、書式指定子(例: %d%s%f)とオプションのフラグ、幅、精度を組み合わせて、出力の形式を細かく制御します。

  • 書式指定子 (Verb): 出力する値の型と基本的な表現方法を指定します(例: %dは整数、%sは文字列、%fは浮動小数点数)。
  • フラグ (Flags): 書式指定子の挙動を変更する追加オプションです(例: +は常に符号を表示、-は左寄せ)。
  • 幅 (Width): 出力されるフィールドの最小幅を指定します。値がこの幅よりも短い場合、通常はスペースでパディングされます。
  • 精度 (Precision):
    • 浮動小数点数に対しては、小数点以下の桁数を指定します。
    • 文字列に対しては、出力される文字列の最大文字数を指定します(これを超えると切り捨てられます)。
    • %g/%Gに対しては、有効数字の総数を指定します。

Unicodeコードポイント

Go言語のfmtパッケージにおける幅と精度の単位は、C言語のprintfがバイト単位であるのに対し、Unicodeコードポイント単位です。これは、マルチバイト文字(例: 日本語の文字)を扱う際に重要になります。例えば、"あ"という文字はUTF-8では3バイトですが、1つのUnicodeコードポイントとして数えられます。したがって、幅や精度を1と指定した場合、"あ"は1文字として扱われ、切り捨てられたりパディングされたりします。

Issue #7048

このコミットが修正するIssue #7048は、fmtパッケージのドキュメンテーションにおける幅と精度の説明が不十分であるという報告です。特に、%f%e%gなどの浮動小数点数フォーマットにおけるデフォルトの精度や、幅と精度の組み合わせによる挙動が不明瞭であることが指摘されていました。

技術的詳細

このコミットは、src/pkg/fmt/doc.goファイル内のドキュメンテーションコメントを修正し、幅と精度の概念をより詳細かつ具体的に説明しています。

主な変更点は以下の通りです。

  1. 幅と精度の定義の明確化:

    • 幅は、書式指定子の直後に続くオプションの10進数で指定されることを明記。
    • 精度は、幅の後にピリオドとそれに続く10進数で指定されることを明記。
    • ピリオドのみで数字が続かない場合は、精度がゼロになることを明確化。
  2. 具体的な例の追加:

    • %f%9f%.2f%9.2f%9.fといった具体的なフォーマット指定子の例と、それらが幅と精度にどのように影響するかを明示的に示しています。これにより、ユーザーは実際のコードでどのように記述すればよいかを直感的に理解できます。
  3. Unicodeコードポイント単位の再強調:

    • 幅と精度がUnicodeコードポイント単位で測定されることを再度強調し、C言語のprintfとの違いを明確にしています。これは、国際化対応されたアプリケーションにおいて特に重要な点です。
  4. 幅と精度の適用範囲の明確化:

    • 以前のドキュメンテーションでは、幅と精度が「数値」と「ほとんどの値」に適用されるという記述が混在していました。今回の変更では、
      • 「ほとんどの値」に対して、幅が最小出力文字数であり、必要に応じてスペースでパディングされることを説明。
      • 「文字列」に対して、精度が最大出力文字数であり、必要に応じて切り捨てられることを説明。
      • 「浮動小数点数」に対して、幅がフィールドの最小幅、精度が小数点以下の桁数(%g/%Gの場合は有効数字の総数)であることを明確に区別して説明しています。
  5. 浮動小数点数のデフォルト精度の説明の改善:

    • %e%fのデフォルト精度が6であること、%gのデフォルト精度が値を一意に識別するために必要な最小桁数であることについて、より詳細な説明が追加されています。
  6. 複素数に対する幅と精度の適用方法の追加:

    • 複素数に対して幅と精度がどのように適用されるか(2つの成分に独立して適用され、結果が括弧で囲まれる)についての説明が追加されました。これは、fmtパッケージが複素数型もサポートしているため、そのフォーマット方法を明確にするものです。

これらの変更により、fmtパッケージのドキュメンテーションは、幅と精度の概念をより体系的かつ具体的に説明し、ユーザーがフォーマット機能をより効果的に活用できるようになっています。

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

--- a/src/pkg/fmt/doc.go
+++ b/src/pkg/fmt/doc.go
@@ -50,23 +50,39 @@
 	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.\n \tSimilarly, there is no need to specify the size of the operand (int8, int64).\n \n-\tThe width and precision control formatting and are in units of Unicode\n-\tcode points.  (This differs from C's printf where the units are numbers\n+\tWidth is specified by an optional decimal number immediately following the verb.\n+\tIf absent, the width is whatever is necessary to represent the value.\n+\tPrecision is specified after the (optional) width by a period followed by a\n+\tdecimal number. If no period is present, a default precision is used.\n+\tA period with no following number specifies a precision of zero.\n+\tExamples:\n+\t\t%f:    default width, default precision\n+\t\t%9f    width 9, default precision\n+\t\t%.2f   default width, precision 2\n+\t\t%9.2f  width 9, precision 2\n+\t\t%9.f   width 9, precision 0\n+\n+\tWidth and precision are measured in units of Unicode code points.\n+\t(This differs from C's printf where the units are numbers\n \tof bytes.) Either or both of the flags may be replaced with the\n \tcharacter '*', causing their values to be obtained from the next\n \toperand, which must be of type int.\n \n-\tFor numeric values, width sets the minimum width of the field and\n+\tFor most values, width is the minimum number of characters to output,\n+\tpadding the formatted form with spaces if necessary.\n+\tFor strings, precision is the maximum number of characters to output,\n+\ttruncating if necessary.\n+\n+\tFor floating-point values, width sets the minimum width of the field and\n \tprecision sets the number of places after the decimal, if appropriate,\n \texcept that for %g/%G it sets the total number of digits. For example,\n \tgiven 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.\n \tThe default precision for %e and %f is 6; for %g it is the smallest\n \tnumber of digits necessary to identify the value uniquely.\n \n-\tFor most values, width is the minimum number of characters to output,\n-\tpadding the formatted form with spaces if necessary.\n-\tFor strings, precision is the maximum number of characters to output,\n-\ttruncating if necessary.\n+\tFor complex numbers, the width and precision apply to the two\n+\tcomponents independently and the result is parenthsized, so %f applied\n+\tto 1.2+3.4i produces (1.200000+3.400000i).\n \n \tOther flags:\n \t\t+\talways print a sign for numeric values;\n```

## コアとなるコードの解説

このコミットは、`src/pkg/fmt/doc.go`ファイル内のドキュメンテーションコメントを修正しています。このファイルは、`fmt`パッケージの公開ドキュメンテーションとして機能し、GoDocツールによって生成されるドキュメントの基になります。

変更の主要なポイントは以下の通りです。

1.  **幅と精度の定義の再構築**:
    *   削除された行 (`- \tThe width and precision control formatting and are in units of Unicode\n- \tcode points.  (This differs from C's printf where the units are numbers`) は、幅と精度の定義をより詳細な説明に置き換えるためのものです。
    *   追加された行 (`+ \tWidth is specified by an optional decimal number immediately following the verb.\n+ \tIf absent, the width is whatever is necessary to represent the value.\n+ \tPrecision is specified after the (optional) width by a period followed by a\n+ \tdecimal number. If no period is present, a default precision is used.\n+ \tA period with no following number specifies a precision of zero.`) は、幅と精度がどのように指定されるか、およびデフォルトの挙動やゼロ精度の指定方法を明確に説明しています。

2.  **具体的なフォーマット例の追加**:
    *   追加された以下の行は、様々な幅と精度の組み合わせがどのように解釈されるかを示す具体的な例です。
        ```
        + \tExamples:
        + \t\t%f:    default width, default precision
        + \t\t%9f    width 9, default precision
        + \t\t%.2f   default width, precision 2
        + \t\t%9.2f  width 9, precision 2
        + \t\t%9.f   width 9, precision 0
        ```
        これにより、ユーザーは実際の使用例を通じて理解を深めることができます。

3.  **Unicodeコードポイント単位の再確認**:
    *   `+ \tWidth and precision are measured in units of Unicode code points.\n+ \t(This differs from C's printf where the units are numbers` は、幅と精度がUnicodeコードポイント単位であることを再度強調し、C言語との違いを明確にしています。

4.  **幅と精度の適用対象の整理**:
    *   削除された行 (`- \tFor numeric values, width sets the minimum width of the field and`) は、数値に対する幅の一般的な説明でした。
    *   追加された行 (`+ \tFor most values, width is the minimum number of characters to output,\n+ \tpadding the formatted form with spaces if necessary.\n+ \tFor strings, precision is the maximum number of characters to output,\n+ \ttruncating if necessary.\n+\n+ \tFor floating-point values, width sets the minimum width of the field and`) は、幅と精度が「ほとんどの値」、「文字列」、「浮動小数点数」それぞれにどのように適用されるかをより具体的に、かつ明確に区別して説明しています。これにより、異なるデータ型に対する挙動の混乱が解消されます。

5.  **複素数に対する説明の追加**:
    *   削除された行 (`- \tFor most values, width is the minimum number of characters to output,\n- \tpadding the formatted form with spaces if necessary.\n- \tFor strings, precision is the maximum number of characters to output,\n- \ttruncating if necessary.`) は、一般的な幅と精度の説明でしたが、より詳細な説明に置き換えられました。
    *   追加された行 (`+ \tFor complex numbers, the width and precision apply to the two\n+ \tcomponents independently and the result is parenthsized, so %f applied\n+ \tto 1.2+3.4i produces (1.200000+3.400000i).`) は、複素数に対する幅と精度の適用方法を具体例とともに示しており、`fmt`パッケージの包括的なドキュメンテーションに貢献しています。

これらの変更は、既存のドキュメンテーションの曖昧な点を解消し、`fmt`パッケージのフォーマット機能に関するユーザーの理解を深める上で非常に重要です。

## 関連リンク

-   Go CL (Code Review) リンク: [https://golang.org/cl/74280044](https://golang.org/cl/74280044)
-   Go Issue #7048: [https://github.com/golang/go/issues/7048](https://github.com/golang/go/issues/7048)

## 参考にした情報源リンク

-   Go言語の`fmt`パッケージ公式ドキュメンテーション: [https://pkg.go.dev/fmt](https://pkg.go.dev/fmt) (このコミットによって改善されたドキュメンテーションの最終的な形がここに反映されています)
-   C言語 `printf` フォーマット指定子に関する一般的な情報 (Goの`fmt`との比較理解のため): [https://en.cppreference.com/w/c/io/fprintf](https://en.cppreference.com/w/c/io/fprintf)
-   Unicodeコードポイントに関する一般的な情報: [https://ja.wikipedia.org/wiki/Unicode%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88](https://ja.wikipedia.org/wiki/Unicode%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)