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

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

このコミットは、Go言語の標準ライブラリstrconvパッケージ内のParseInt関数のドキュメントを更新するものです。具体的には、ParseInt関数がエラーを返した場合に、同時に返される数値(int64)がどのような値になるのかを明確に記述しています。これは既存の挙動を文書化したものであり、コードの動作自体に変更はありません。

コミット

commit c0d4576593906e169f367e7c61d94ed37cc782b8
Author: Rob Pike <r@golang.org>
Date:   Fri Mar 7 13:23:50 2014 +1100

    strconv: document value returned by ParseInt when there is an error
    Documenting existing behavior; new commentary only.
    Fixes #7105.
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/68840044

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

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

元コミット内容

strconv: document value returned by ParseInt when there is an error
Documenting existing behavior; new commentary only.
Fixes #7105.

変更の背景

strconv.ParseInt関数は、文字列を整数に変換する際に、変換に失敗した場合にエラーを返します。しかし、エラーが発生した際に、同時に返されるint64型の戻り値がどのような値になるのかが、以前のドキュメントでは不明確でした。

プログラミングにおいて、関数が複数の戻り値を持ち、そのうちの一つがエラーである場合、エラーでない戻り値がエラー時にどのような状態になるのかを明確にすることは非常に重要です。これにより、開発者はエラーハンドリングのロジックをより正確に記述でき、予期せぬ動作やバグを防ぐことができます。

このコミットは、既存のParseIntの挙動(エラー時の戻り値)を明示的にドキュメントに追加することで、APIの明確性を向上させ、開発者がより安全にParseIntを使用できるようにすることを目的としています。Fixes #7105とありますが、Web検索の結果からはこのIssueがstrconv.ParseIntに直接関連する具体的なバグ報告や機能要望ではないようです。しかし、ドキュメントの改善という観点から、このコミットがユーザーからのフィードバックや内部的なレビューに基づいて行われた可能性はあります。

前提知識の解説

strconvパッケージ

strconvパッケージは、Go言語の標準ライブラリの一部で、基本的なデータ型(文字列、整数、浮動小数点数、真偽値など)とそれらの文字列表現との間の変換機能を提供します。例えば、Atoi(文字列から整数へ)、Itoa(整数から文字列へ)、ParseBoolFormatFloatなどの関数があります。

strconv.ParseInt関数

ParseInt関数は、文字列sを、指定された基数base(2から36)とビットサイズbitSize(0, 8, 16, 32, 64)に基づいてint64型の整数に変換します。

  • s: 変換する文字列。
  • base: 基数。0を指定すると、文字列のプレフィックス("0x"は16進数、"0"または"0o"は8進数、"0b"は2進数)から自動的に基数を推測します。それ以外の場合は、2から36の間の値を指定します。
  • bitSize: 結果が収まるべき整数のビットサイズ。0はint、8はint8、16はint16、32はint32、64はint64に対応します。

ParseIntは2つの値を返します。1つ目は変換されたint64型の値、2つ目はエラー(errorインターフェース型)です。

*NumError

strconvパッケージの変換関数がエラーを返す場合、そのエラーは通常、*NumErrorという具象型になります。NumError構造体は以下のフィールドを持ちます。

  • Func: エラーが発生した関数の名前(例: "ParseInt")。
  • Num: 変換しようとした元の文字列。
  • Err: 発生したエラーの種類を示すエラー値。

ErrSyntaxErrRange

*NumErrorErrフィールドには、主に以下の2つのエラー値が設定されます。

  • ErrSyntax: 構文エラーを示します。これは、入力文字列が空である場合や、指定された基数に対して無効な文字が含まれている場合に発生します。例えば、ParseInt("abc", 10, 64)のように、数字ではない文字が含まれる場合です。
  • ErrRange: 範囲エラーを示します。これは、変換された数値が、指定されたbitSizeで表現できる範囲を超えている場合に発生します。例えば、ParseInt("9223372036854775808", 10, 64)のように、int64の最大値を超える数値を変換しようとした場合です。

技術的詳細

このコミットの技術的な詳細は、strconv.ParseInt関数のドキュメントコメントの変更に集約されます。変更前は、エラーの種類(ErrSyntaxErrRange)についてのみ言及されていましたが、変更後は、それぞれのエラーが発生した際にParseIntが返すint64の値が具体的に記述されています。

ErrSyntaxの場合の挙動の明確化

変更前: If s is empty or contains invalid digits, err.Err = ErrSyntax; (sが空であるか、無効な数字を含む場合、err.Err = ErrSyntax;)

変更後: If s is empty or contains invalid digits, err.Err = ErrSyntax and the returned value is 0; (sが空であるか、無効な数字を含む場合、err.Err = ErrSyntax かつ返される値は0です;)

これにより、構文エラーが発生した場合、ParseIntはエラーを返すだけでなく、数値の戻り値としては0を返すことが明確になりました。これは、変換が全く行えなかった場合の安全なデフォルト値として機能します。

ErrRangeの場合の挙動の明確化

変更前: if the value corresponding to s cannot be represented by a signed integer of the given size, err.Err = ErrRange. (sに対応する値が指定されたサイズの符号付き整数で表現できない場合、err.Err = ErrRange.)

変更後: if the value corresponding to s cannot be represented by a signed integer of the given size, err.Err = ErrRange and the returned value is the maximum magnitude integer of the appropriate bitSize and sign. (sに対応する値が指定されたサイズの符号付き整数で表現できない場合、err.Err = ErrRange かつ返される値は、適切なbitSizeと符号を持つ最大絶対値の整数です。)

この変更はより詳細です。範囲エラーが発生した場合、ParseIntは単にエラーを返すだけでなく、以下の規則に従って数値を返します。

  • 最大絶対値の整数: これは、指定されたbitSizeで表現できる最大値または最小値(絶対値が最大となる値)を意味します。
  • 適切なbitSizeと符号:
    • もし元の文字列が正の数で、それがbitSizeの最大値を超えた場合、ParseIntbitSizeで表現できる最大の正の整数(例: int64の場合はmath.MaxInt64)を返します。
    • もし元の文字列が負の数で、それがbitSizeの最小値を超えた場合、ParseIntbitSizeで表現できる最小の負の整数(例: int64の場合はmath.MinInt64)を返します。

この挙動は、数値が範囲外であったとしても、その方向性(正の方向か負の方向か)をある程度示すためのものです。例えば、非常に大きな正の数をパースしようとしてErrRangeになった場合、返される値がMaxInt64であれば、元の数が正の方向でオーバーフローしたことが推測できます。

これらのドキュメントの追加により、ParseIntの戻り値のセマンティクスが完全に明確になり、開発者はエラー発生時にも返された数値を利用したロジックを安全に構築できるようになります。

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

変更はsrc/pkg/strconv/atoi.goファイルのコメント部分のみです。

--- a/src/pkg/strconv/atoi.go
+++ b/src/pkg/strconv/atoi.go
@@ -142,9 +142,11 @@ Error:
 //
 // The errors that ParseInt returns have concrete type *NumError
 // and include err.Num = s.  If s is empty or contains invalid
-// digits, err.Err = ErrSyntax; if the value corresponding
-// to s cannot be represented by a signed integer of the
-// given size, err.Err = ErrRange.
+// digits, err.Err = ErrSyntax and the returned value is 0;
+// if the value corresponding to s cannot be represented by a
+// signed integer of the given size, err.Err = ErrRange and the
+// returned value is the maximum magnitude integer of the
+// appropriate bitSize and sign.
 func ParseInt(s string, base int, bitSize int) (i int64, err error) {
 	const fnParseInt = "ParseInt"

コアとなるコードの解説

変更されたのは、ParseInt関数のドキュメントコメント内の以下の部分です。

元のコメント:

// digits, err.Err = ErrSyntax; if the value corresponding
// to s cannot be represented by a signed integer of the
// given size, err.Err = ErrRange.

変更後のコメント:

// digits, err.Err = ErrSyntax and the returned value is 0;
// if the value corresponding to s cannot be represented by a
// signed integer of the given size, err.Err = ErrRange and the
// returned value is the maximum magnitude integer of the
// appropriate bitSize and sign.

この変更は、ParseIntがエラーを返す際に、同時に返されるint64の値がどうなるかを明示的に記述しています。

  1. ErrSyntaxの場合:

    • err.Err = ErrSyntax and the returned value is 0;」という記述が追加されました。
    • これは、入力文字列の構文が不正(例: 空文字列、無効な文字を含む)であるためにErrSyntaxエラーが発生した場合、ParseIntint64の戻り値として0を返すことを意味します。
  2. ErrRangeの場合:

    • err.Err = ErrRange and the returned value is the maximum magnitude integer of the appropriate bitSize and sign.」という記述が追加されました。
    • これは、変換しようとした数値が指定されたbitSizeの範囲を超えてErrRangeエラーが発生した場合、ParseIntint64の戻り値として、そのbitSizeで表現できる最大絶対値の整数(例: int64の最大値math.MaxInt64または最小値math.MinInt64)を返すことを意味します。返される値の符号は、元の文字列が表す数値の符号と一致します。

これらの変更は、ParseIntのAPI契約をより明確にし、開発者がエラー発生時の戻り値の挙動を正確に理解し、それに基づいて堅牢なコードを書くことを可能にします。

関連リンク

参考にした情報源リンク