[インデックス 1757] ファイルの概要
このコミットは、Go言語の標準ライブラリであるstrconv
パッケージのドキュメンテーションを大幅に改善することを目的としています。strconv
パッケージは、文字列と基本的なデータ型(数値、真偽値など)の間での変換機能を提供します。このコミットでは、既存の関数に詳細なコメントを追加し、一部の関数の引数順序を変更することで、APIの明確性と使いやすさを向上させています。
コミット
commit 5bf0fbe7a8a3c3199956cf6f796b26074076ab1a
Author: Russ Cox <rsc@golang.org>
Date: Thu Mar 5 15:29:04 2009 -0800
strconv: doc
R=r
DELTA=110 (64 added, 19 deleted, 27 changed)
OCL=25761
CL=25782
---
src/lib/strconv/atof.go | 32 ++++++++++++++++++-------------\
src/lib/strconv/atoi.go | 49 ++++++++++++++++++++++++++++--------------------\
src/lib/strconv/ftoa.go | 23 +++++++++++++++++++++++
src/lib/strconv/itoa.go | 7 ++++---\
src/lib/strconv/quote.go | 6 ++++++\
5 files changed, 81 insertions(+), 36 deletions(-)
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5bf0fbe7a8a3c3199956cf6f796b26074076ab1a
元コミット内容
このコミットの元の内容は、非常に簡潔に「strconv: doc」とだけ記されています。これは、strconv
パッケージに対するドキュメンテーションの追加が主な変更点であることを示唆しています。
変更の背景
Go言語は、その設計思想として「シンプルさ」と「明確さ」を重視しています。初期のGo言語開発段階において、標準ライブラリのAPIは機能が実装されていく一方で、その利用方法や挙動に関する詳細なドキュメンテーションが不足していることがありました。特に、文字列と数値の変換を行うstrconv
パッケージのような基本的なユーティリティは、開発者が頻繁に利用するため、その挙動が明確に定義され、ドキュメント化されていることが極めて重要です。
このコミットは、以下の目的のために行われました。
- APIの明確化: 各関数の目的、引数、戻り値、エラー条件などを詳細に記述することで、開発者が関数を正しく理解し、利用できるようにする。
- エラーハンドリングの指針:
os.EINVAL
やos.ERANGE
といった特定のエラーがどのような状況で返されるかを明記し、適切なエラーハンドリングを促す。 - 一貫性の向上:
strconv
パッケージ内の関数間でドキュメンテーションのスタイルと詳細度を統一する。 - 引数順序の改善:
Btoui64
関数の引数順序を、より直感的で一般的なパターン(変換対象の文字列が先に来る)に変更し、APIの一貫性を高める。これは単なるドキュメンテーションの追加だけでなく、APIの使いやすさに関わる重要な変更です。
これらの改善は、Go言語が成熟していく過程で、ライブラリの品質と開発者体験を向上させるための継続的な取り組みの一環として行われました。
前提知識の解説
strconv
パッケージ
strconv
パッケージは、Go言語の標準ライブラリの一部であり、文字列とGoの組み込みデータ型(ブール値、整数、浮動小数点数)の間で変換を行うための機能を提供します。例えば、文字列"123"を整数123に変換したり、浮動小数点数3.14を文字列"3.14"に変換したりする際に使用されます。
主要な機能カテゴリは以下の通りです。
- 文字列から数値への変換:
Atoi
(文字列からintへ),ParseInt
(文字列からint64へ、基数指定可能),ParseFloat
(文字列からfloatへ) など。 - 数値から文字列への変換:
Itoa
(intから文字列へ),FormatInt
(int64から文字列へ、基数指定可能),FormatFloat
(floatから文字列へ、フォーマット指定可能) など。 - 真偽値の変換:
ParseBool
,FormatBool
。 - クォーティング: 文字列をGoの文字列リテラル形式に変換する
Quote
など。
IEEE 754 浮動小数点数標準
浮動小数点数の変換(Atof
やFtoa
関連)では、IEEE 754標準が重要な役割を果たします。これは、浮動小数点数の表現と演算に関する国際標準です。
- 単精度 (float32): 32ビットで表現され、約7桁の10進精度を持ちます。
- 倍精度 (float64): 64ビットで表現され、約15-17桁の10進精度を持ちます。
strconv
パッケージの浮動小数点数変換関数は、この標準に従って丸め処理(IEEE754 unbiased rounding)やオーバーフロー/アンダーフローの検出を行います。特に、文字列から浮動小数点数への変換では、入力文字列が正確に表現できない場合、最も近い浮動小数点数に丸められます。
基数変換 (Radix Conversion)
整数変換(Atoi
やItoa
関連)では、数値の基数(進数)が関係します。
- 10進数 (Decimal): 日常的に使用される基数10のシステム。
- 8進数 (Octal): 基数8のシステム。Goでは
0
で始まる数値リテラルで表現されます(例:0755
)。 - 16進数 (Hexadecimal): 基数16のシステム。Goでは
0x
または0X
で始まる数値リテラルで表現されます(例:0xFF
)。
strconv
パッケージの関数は、これらの基数での文字列表現と数値表現の間の変換をサポートしています。
Go言語のエラーハンドリング
Go言語では、エラーは多値戻り値の最後の値として返されるのが一般的です。strconv
パッケージの変換関数もこのパターンに従い、変換が成功した場合はnil
を、失敗した場合は*os.Error
型の値を返します。
os.EINVAL
: 無効な引数、または構文的に不正な入力文字列が与えられた場合に返されます。os.ERANGE
: 変換結果が対象の型で表現できる範囲を超えている(オーバーフローまたはアンダーフロー)場合に返されます。
技術的詳細
このコミットは、主にstrconv
パッケージ内の以下の主要な変換関数にドキュメンテーションを追加しています。
-
浮動小数点数変換 (
atof.go
,ftoa.go
):Atof32
,Atof64
: 文字列をそれぞれfloat32
、float64
に変換します。ドキュメントでは、入力文字列の構文が不正な場合のos.EINVAL
、値が範囲外の場合のos.ERANGE
の返却条件が明確化されました。また、IEEE754の丸め規則についても言及されています。Ftoa32
,Ftoa64
:float32
、float64
を文字列に変換します。フォーマット('b'
,'e'
,'f'
,'g'
)と精度(prec
)の指定方法が詳細に説明されています。特に、prec = -1
が「Atof32
がf
を正確に返すために必要な最小桁数」を意味することが明記されました。Atof
,Ftoa
:float
型(Goのfloat
はfloat32
またはfloat64
のエイリアス)に対する汎用的な変換関数であり、内部的にFloatSize
変数に基づいてAtof32
/Atof64
またはFtoa32
/Ftoa64
を呼び出すことが説明されています。
-
整数変換 (
atoi.go
,itoa.go
):Btoui64
: 任意の基数(2〜36)の文字列をuint64
に変換します。この関数は、引数の順序が(base int, s string)
から(s string, b int)
に変更されました。 これは、変換対象の文字列s
が第一引数に来るという、Goの他の多くの変換関数(例:ParseInt
)との一貫性を高めるための重要なAPI変更です。ドキュメントでは、基数の範囲、空文字列、無効な桁、およびオーバーフロー(os.ERANGE
)の条件が詳細に記述されました。Atoui64
,Atoi64
: 文字列をそれぞれuint64
、int64
に変換します。0x
プレフィックスによる16進数、0
プレフィックスによる8進数、それ以外は10進数として解釈されることが明記されました。エラー条件(空文字列、無効な桁、範囲外)も詳細化されています。Atoui
,Atoi
:Atoui64
、Atoi64
と同様ですが、結果をそれぞれuint
、int
型で返します。uint
やint
の最大値を超える場合のos.ERANGE
の扱いについても言及されています。Itob64
,Itoa64
:int64
を任意の基数または10進数の文字列に変換します。Itob
,Itoa
:int
を任意の基数または10進数の文字列に変換します。
-
クォーティング (
quote.go
):Quote
: 文字列をGoのダブルクォートされた文字列リテラル形式に変換します。制御文字や非ASCII文字がGoのエスケープシーケンス(例:\t
,\n
,\xFF
,\u0100
)に変換されることが説明されています。CanBackquote
: 文字列がバッククォート(
全体として、このコミットはstrconv
パッケージのAPIドキュメンテーションを大幅に強化し、開発者がこれらの変換関数をより安全かつ効果的に使用できるようにするための基盤を築いています。特にBtoui64
の引数順序変更は、APIの一貫性を高める上で重要な改善点です。
コアとなるコードの変更箇所
このコミットにおける最も顕著な変更は、既存の関数定義に詳細なコメント(GoDoc)が追加されたことです。また、Btoui64
関数の引数順序が変更されています。
以下に、src/lib/strconv/atoi.go
におけるBtoui64
関数の変更を例として示します。
変更前 (src/lib/strconv/atoi.go
):
// Convert arbitrary base string to unsigned integer.
func Btoui64(base int, s string) (n uint64, err *os.Error) {
if base < 2 || base > 36 || len(s) < 1 {
return 0, os.EINVAL;
}
n = 0;
cutoff := cutoff64(base);
for i := 0; i < len(s); i++ {
var v byte;
switch {
case '0' <= s[i] && s[i] <= '9':
v = s[i] - '0';
case 'a' <= s[i] && s[i] <= 'z':
v = s[i] - 'a' + 10;
case 'A' <= s[i] && s[i] <= 'Z':
v = s[i] - 'A' + 10;
default:
return 0, os.EINVAL;
}
if int(v) >= base {
return 0, os.EINVAL;
}
if n >= cutoff {
// n*base overflows
return 1<<64-1, os.ERANGE;
}
n *= uint64(base);
n1 := n+uint64(v);
if n1 < n {
// n+v overflows
return 1<<64-1, os.ERANGE;
}
n = n1;
}
return n, nil;
}
変更後 (src/lib/strconv/atoi.go
):
// Btoui64 interprets a string s in an arbitrary base b (2 to 36)
// and returns the corresponding value n.
//
// Btoui64 returns err == os.EINVAL if b is out of
// range or s is empty or contains invalid digits.
// It returns err == os.ERANGE if the value corresponding
// to s cannot be represented by a uint64.
func Btoui64(s string, b int) (n uint64, err *os.Error) {
if b < 2 || b > 36 || len(s) < 1 {
return 0, os.EINVAL;
}
n = 0;
cutoff := cutoff64(b); // base -> b
for i := 0; i < len(s); i++ {
var v byte;
switch {
case '0' <= s[i] && s[i] <= '9':
v = s[i] - '0';
case 'a' <= s[i] && s[i] <= 'z':
v = s[i] - 'a' + 10;
case 'A' <= s[i] && s[i] <= 'Z':
v = s[i] - 'A' + 10;
default:
return 0, os.EINVAL;
}
if int(v) >= b { // base -> b
return 0, os.EINVAL;
}
if n >= cutoff {
// n*b overflows // n*base overflows -> n*b overflows
return 1<<64-1, os.ERANGE;
}
n *= uint64(b); // base -> b
n1 := n+uint64(v);
if n1 < n {
// n+v overflows
return 1<<64-1, os.ERANGE;
}
n = n1;
}
return n, nil;
}
コアとなるコードの解説
上記のBtoui64
関数の変更は、以下の2つの側面で重要です。
-
ドキュメンテーションの追加:
- 変更前は「Convert arbitrary base string to unsigned integer.」という簡潔なコメントしかありませんでした。
- 変更後には、GoDoc形式で関数の目的、引数
s
とb
の意味、そしてos.EINVAL
とos.ERANGE
が返される具体的な条件が詳細に記述されています。これにより、開発者はこの関数がどのような入力を期待し、どのようなエラーを返す可能性があるかを一目で理解できるようになります。
-
引数順序の変更:
- 変更前は
func Btoui64(base int, s string)
というシグネチャでした。 - 変更後には
func Btoui64(s string, b int)
となり、変換対象の文字列s
が第一引数に、基数b
が第二引数に来るようになりました。 - この変更は、Go言語の標準ライブラリにおける一般的なAPI設計パターン(例えば、
strings.Contains(s, substr string)
のように、操作対象のデータが第一引数に来る)に合わせたものです。これにより、strconv
パッケージ内の他の関数(例:ParseInt(s string, base int, bitSize int)
)との一貫性が向上し、APIの学習コストが低減されます。 - 引数名の変更(
base
からb
へ)も、より簡潔な命名規則への移行を示しています。 - 関数本体内の
base
変数の参照もすべてb
に更新されています。
- 変更前は
このコミットは、単にコメントを追加するだけでなく、APIの使いやすさと一貫性を向上させるための細かな調整も含まれていることを示しています。このような改善は、Go言語のライブラリが長期的にメンテナンスされ、広く利用される上で不可欠な要素です。
関連リンク
- Go言語
strconv
パッケージのドキュメント (現在のバージョン): https://pkg.go.dev/strconv - Go言語のソースコードリポジトリ (GitHub): https://github.com/golang/go
参考にした情報源リンク
- IEEE 754 浮動小数点数標準に関する情報 (Wikipedia): https://ja.wikipedia.org/wiki/IEEE_754
- Go言語のエラーハンドリングに関する一般的な情報: https://go.dev/blog/error-handling-and-go
- Go言語のGoDocに関する情報: https://go.dev/blog/godoc
- Go言語のAPI設計に関する一般的なガイドライン (Effective Goなど): https://go.dev/doc/effective_go
- Go言語の
strconv
パッケージの歴史的な変更点 (Goのリリースノートなど): https://go.dev/doc/devel/release (このコミットはGoの非常に初期の段階のものであるため、直接的なリリースノートの言及は少ない可能性がありますが、一般的な情報源として記載)