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

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

このコミットは、Go言語の標準ライブラリであるregexpパッケージのドキュメントにおける軽微なバグ修正を目的としています。具体的には、正規表現の置換処理に関する説明で、バイトスライスと文字列の区別が曖昧であった点を修正し、より正確な表現に改められています。

コミット

commit 43cf5505fcc3cdf4d02a4970af0b8a441ac274ef
Author: Rob Pike <r@golang.org>
Date:   Wed May 30 21:57:50 2012 -0700

    regexp: fix a couple of bugs in the documentation
    Byte slices are not strings.
    
    Fixes #3687.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/6257074

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

https://github.com/golang/go/commit/43cf5505fcc3cdf4d02a4970af0b8a441ac274ef

元コミット内容

regexp: fix a couple of bugs in the documentation
Byte slices are not strings.

Fixes #3687.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/6257074

変更の背景

このコミットは、Go言語のregexpパッケージのドキュメントにおける誤解を招く表現を修正するために行われました。特に、Regexp.ReplaceAllメソッドの説明において、置換文字列(repl)が実際にはバイトスライスであるにもかかわらず、「replacement string」と記述されていた点、および、正規表現のサブマッチが範囲外または不一致の場合に「empty string」ではなく「empty slice」で置換されるべきであるという点が問題視されました。

Go言語では、文字列(string)とバイトスライス([]byte)は異なる型であり、それぞれ異なる用途と特性を持っています。文字列は不変のUTF-8エンコードされたバイト列を表し、バイトスライスは任意のバイト列を表す可変のシーケンスです。regexpパッケージの多くの関数は、効率性や柔軟性のためにバイトスライスを直接操作します。ドキュメントがこれらの型の違いを正確に反映していない場合、開発者が誤った仮定に基づいてコードを記述し、予期せぬバグや非効率な処理を引き起こす可能性があります。

この修正は、Go言語のドキュメントの正確性を高め、開発者がregexpパッケージをより適切に利用できるようにすることを目的としています。コミットメッセージに「Fixes #3687」とあることから、この変更は特定のバグ報告(Issue 3687)に対応するものであることがわかります。

前提知識の解説

Go言語におけるstring[]byte

Go言語において、string型と[]byte型は密接に関連していますが、重要な違いがあります。

  • string:

    • 不変(immutable)なバイトのシーケンスです。一度作成されると内容を変更できません。
    • Goの仕様では、文字列はUTF-8エンコードされたテキストを表すことが保証されています。
    • 文字列リテラル(例: "hello")はstring型です。
    • 文字列の結合や部分文字列の抽出は、新しい文字列を生成します。
    • 文字列は、内部的にはバイトの配列へのポインタと長さで表現されます。
  • []byte型(バイトスライス):

    • 可変(mutable)なバイトのシーケンスです。内容を変更できます。
    • 任意のバイト列を表すことができ、テキストデータに限らず、バイナリデータ(画像、音声など)の操作にも使用されます。
    • スライスは、基となる配列へのポインタ、長さ、容量で構成されます。
    • make([]byte, length, capacity)で作成したり、既存の配列や他のスライスから派生させたりできます。

なぜこの区別が重要か?

regexpパッケージのような低レベルのバイト操作を行うライブラリでは、string[]byteの区別はパフォーマンスと正確性の両面で重要です。

  • パフォーマンス: []byteは可変であるため、メモリの再割り当てを最小限に抑えながら、バイト列を効率的に操作できます。一方、stringは不変であるため、変更が必要な操作(例: 置換)では常に新しい文字列が生成され、メモリ割り当てとガベージコレクションのオーバーヘッドが発生する可能性があります。
  • 正確性: regexpパッケージは、正規表現のマッチングと置換をバイトレベルで行います。入力がUTF-8エンコードされた文字列であると仮定するのではなく、任意のバイト列として扱うことで、より汎用的な処理が可能になります。ドキュメントがこの事実を正確に反映していないと、開発者はstring型を期待して不適切な操作を行い、ランタイムエラーや意図しない結果を招く可能性があります。

Go言語のregexpパッケージ

Go言語のregexpパッケージは、正規表現による文字列(またはバイトスライス)のマッチングと操作を提供します。Perlのような正規表現構文をサポートしており、非常に高速な実行が特徴です。

  • Regexp: コンパイルされた正規表現を表す構造体です。
  • Compile関数: 正規表現パターン文字列をRegexpオブジェクトにコンパイルします。
  • ReplaceAllメソッド: 正規表現にマッチするすべての部分を、指定された置換テキストで置き換えます。このメソッドは、入力と置換テキストの両方で[]byte型を受け取ります。

$1などのサブマッチ参照

正規表現の置換パターンにおいて、$1, $2, ... はキャプチャグループ(サブマッチ)を参照するために使用されます。例えば、正規表現が(hello) (world)で、置換パターンが$2 $1の場合、「hello world」は「world hello」に置換されます。$name形式は、名前付きキャプチャグループを参照します。

技術的詳細

このコミットは、src/pkg/regexp/regexp.goファイル内のドキュメントコメントを修正しています。具体的には、以下の2つの箇所が変更されました。

  1. Regexp.ReplaceAllメソッドのコメント修正:

    • 変更前: // with the replacement string repl.
    • 変更後: // with the replacement text repl.
    • この修正は、「string」という単語を「text」に置き換えることで、repl引数が[]byte型であることをより正確に示しています。[]byteは任意のバイト列であり、必ずしもUTF-8エンコードされた「string」であるとは限らないため、この変更は型の正確性を向上させます。
  2. Regexp.FindSubmatch関連のコメント修正(サブマッチ参照の挙動):

    • 変更前: // present in the regular expression is replaced with an empty string.
    • 変更後: // present in the regular expression is replaced with an empty slice.
    • この修正は、正規表現のサブマッチ参照(例: $1)において、対応するインデックスや名前が見つからない場合に、空の「string」ではなく空の「slice」(すなわち[]byte{})で置換されることを明確にしています。これは、regexpパッケージがバイトスライスを操作する性質と一貫しています。

これらの変更は、コードの動作自体を変更するものではなく、あくまでドキュメントの記述を実際の挙動とGo言語の型システムに合致させるためのものです。これにより、開発者がregexpパッケージの関数やメソッドの引数と戻り値の型について誤解するリスクが低減されます。

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

--- a/src/pkg/regexp/regexp.go
+++ b/src/pkg/regexp/regexp.go
@@ -512,7 +512,7 @@ func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst
 }
 
 // ReplaceAll returns a copy of src, replacing matches of the Regexp
-// with the replacement string repl.  Inside repl, $ signs are interpreted as
+// with the replacement text repl.  Inside repl, $ signs are interpreted as
 // in Expand, so for instance $1 represents the text of the first submatch.
 func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
 	n := 2
@@ -726,7 +726,7 @@ func (re *Regexp) FindSubmatch(b []byte) [][]byte {
 // the submatch with the corresponding index; other names refer to
 // capturing parentheses named with the (?P<name>...) syntax.  A
 // reference to an out of range or unmatched index or a name that is not
-// present in the regular expression is replaced with an empty string.
+// present in the regular expression is replaced with an empty slice.
 // 
 // In the $name form, name is taken to be as long as possible: $1x is
 // equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.

コアとなるコードの解説

上記のdiffは、src/pkg/regexp/regexp.goファイル内の2つのコメント行に対する変更を示しています。

  1. Regexp.ReplaceAllメソッドのコメント (行515):

    • 元のコメント: // with the replacement string repl.
    • 修正後のコメント: // with the replacement text repl.
    • この行は、Regexp.ReplaceAllメソッドが正規表現にマッチした部分を何で置換するかを説明しています。ReplaceAllメソッドのシグネチャはfunc (re *Regexp) ReplaceAll(src, repl []byte) []byteであり、repl引数は[]byte型です。元のコメントでは「string」と記述されていましたが、これはGo言語の型システムにおける「string」型とは異なるため、「text」というより一般的な用語に修正されました。これにより、replがバイトスライスであることをより正確に示し、開発者の誤解を防ぎます。
  2. サブマッチ参照の挙動に関するコメント (行729):

    • 元のコメント: // present in the regular expression is replaced with an empty string.
    • 修正後のコメント: // present in the regular expression is replaced with an empty slice.
    • この行は、正規表現の置換パターン内で$1のようなサブマッチ参照が使用され、その参照が有効なサブマッチに対応しない場合に何が起こるかを説明しています。元のコメントでは「empty string」で置換されると記述されていましたが、実際には空のバイトスライス([]byte{})が使用されます。この修正は、regexpパッケージがバイトスライスを基盤として操作するという事実と整合性を保つためのものです。

これらの変更は、Go言語のドキュメントの品質と正確性を向上させるための、細部へのこだわりを示しています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコード(src/pkg/regexp/regexp.go
  • GitHubのコミット履歴
  • Go言語のIssueトラッカー(Issue #3687に関する詳細情報があれば)
    • Issue 3687の具体的な内容は、公開されているGoのIssueトラッカーで検索することで確認できます。通常、golang/goリポジトリのIssueセクションで番号を検索します。

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

このコミットは、Go言語の標準ライブラリであるregexpパッケージのドキュメントにおける軽微なバグ修正を目的としています。具体的には、正規表現の置換処理に関する説明で、バイトスライスと文字列の区別が曖昧であった点を修正し、より正確な表現に改められています。

コミット

commit 43cf5505fcc3cdf4d02a4970af0b8a441ac274ef
Author: Rob Pike <r@golang.org>
Date:   Wed May 30 21:57:50 2012 -0700

    regexp: fix a couple of bugs in the documentation
    Byte slices are not strings.
    
    Fixes #3687.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/6257074

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

https://github.com/golang/go/commit/43cf5505fcc3cdf4d02a4970af0b8a441ac274ef

元コミット内容

regexp: fix a couple of bugs in the documentation
Byte slices are not strings.

Fixes #3687.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/6257074

変更の背景

このコミットは、Go言語のregexpパッケージのドキュメントにおける誤解を招く表現を修正するために行われました。特に、Regexp.ReplaceAllメソッドの説明において、置換文字列(repl)が実際にはバイトスライスであるにもかかわらず、「replacement string」と記述されていた点、および、正規表現のサブマッチが範囲外または不一致の場合に「empty string」ではなく「empty slice」で置換されるべきであるという点が問題視されました。

Go言語では、文字列(string)とバイトスライス([]byte)は異なる型であり、それぞれ異なる用途と特性を持っています。文字列は不変のUTF-8エンコードされたバイト列を表し、バイトスライスは任意のバイト列を表す可変のシーケンスです。regexpパッケージの多くの関数は、効率性や柔軟性のためにバイトスライスを直接操作します。ドキュメントがこれらの型の違いを正確に反映していない場合、開発者が誤った仮定に基づいてコードを記述し、予期せぬバグや非効率な処理を引き起こす可能性があります。

この修正は、Go言語のドキュメントの正確性を高め、開発者がregexpパッケージをより適切に利用できるようにすることを目的としています。コミットメッセージに「Fixes #3687」とあることから、この変更は特定のバグ報告(Issue 3687)に対応するものであることがわかります。

前提知識の解説

Go言語におけるstring[]byte

Go言語において、string型と[]byte型は密接に関連していますが、重要な違いがあります。

  • string:

    • 不変(immutable)なバイトのシーケンスです。一度作成されると内容を変更できません。
    • Goの仕様では、文字列はUTF-8エンコードされたテキストを表すことが保証されています。
    • 文字列リテラル(例: "hello")はstring型です。
    • 文字列の結合や部分文字列の抽出は、新しい文字列を生成します。
    • 文字列は、内部的にはバイトの配列へのポインタと長さで表現されます。
  • []byte型(バイトスライス):

    • 可変(mutable)なバイトのシーケンスです。内容を変更できます。
    • 任意のバイト列を表すことができ、テキストデータに限らず、バイナリデータ(画像、音声など)の操作にも使用されます。
    • スライスは、基となる配列へのポインタ、長さ、容量で構成されます。
    • make([]byte, length, capacity)で作成したり、既存の配列や他のスライスから派生させたりできます。

なぜこの区別が重要か?

regexpパッケージのような低レベルのバイト操作を行うライブラリでは、string[]byteの区別はパフォーマンスと正確性の両面で重要です。

  • パフォーマンス: []byteは可変であるため、メモリの再割り当てを最小限に抑えながら、バイト列を効率的に操作できます。一方、stringは不変であるため、変更が必要な操作(例: 置換)では常に新しい文字列が生成され、メモリ割り当てとガベージコレクションのオーバーヘッドが発生する可能性があります。
  • 正確性: regexpパッケージは、正規表現のマッチングと置換をバイトレベルで行います。入力がUTF-8エンコードされた文字列であると仮定するのではなく、任意のバイト列として扱うことで、より汎用的な処理が可能になります。ドキュメントがこの事実を正確に反映していないと、開発者はstring型を期待して不適切な操作を行い、ランタイムエラーや意図しない結果を招く可能性があります。

Go言語のregexpパッケージ

Go言語のregexpパッケージは、正規表現による文字列(またはバイトスライス)のマッチングと操作を提供します。Perlのような正規表現構文をサポートしており、非常に高速な実行が特徴です。

  • Regexp: コンパイルされた正規表現を表す構造体です。
  • Compile関数: 正規表現パターン文字列をRegexpオブジェクトにコンパイルします。
  • ReplaceAllメソッド: 正規表現にマッチするすべての部分を、指定された置換テキストで置き換えます。このメソッドは、入力と置換テキストの両方で[]byte型を受け取ります。

$1などのサブマッチ参照

正規表現の置換パターンにおいて、$1, $2, ... はキャプチャグループ(サブマッチ)を参照するために使用されます。例えば、正規表現が(hello) (world)で、置換パターンが$2 $1の場合、「hello world」は「world hello」に置換されます。$name形式は、名前付きキャプチャグループを参照します。

技術的詳細

このコミットは、src/pkg/regexp/regexp.goファイル内のドキュメントコメントを修正しています。具体的には、以下の2つの箇所が変更されました。

  1. Regexp.ReplaceAllメソッドのコメント修正:

    • 変更前: // with the replacement string repl.
    • 変更後: // with the replacement text repl.
    • この修正は、「string」という単語を「text」に置き換えることで、repl引数が[]byte型であることをより正確に示しています。[]byteは任意のバイト列であり、必ずしもUTF-8エンコードされた「string」であるとは限らないため、この変更は型の正確性を向上させます。
  2. Regexp.FindSubmatch関連のコメント修正(サブマッチ参照の挙動):

    • 変更前: // present in the regular expression is replaced with an empty string.
    • 変更後: // present in the regular expression is replaced with an empty slice.
    • この修正は、正規表現のサブマッチ参照(例: $1)において、対応するインデックスや名前が見つからない場合に、空の「string」ではなく空の「slice」(すなわち[]byte{})で置換されることを明確にしています。これは、regexpパッケージがバイトスライスを操作する性質と一貫しています。

これらの変更は、コードの動作自体を変更するものではなく、あくまでドキュメントの記述を実際の挙動とGo言語の型システムに合致させるためのものです。これにより、開発者がregexpパッケージの関数やメソッドの引数と戻り値の型について誤解するリスクが低減されます。

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

--- a/src/pkg/regexp/regexp.go
+++ b/src/pkg/regexp/regexp.go
@@ -512,7 +512,7 @@ func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst
 }
 
 // ReplaceAll returns a copy of src, replacing matches of the Regexp
-// with the replacement string repl.  Inside repl, $ signs are interpreted as
+// with the replacement text repl.  Inside repl, $ signs are interpreted as
 // in Expand, so for instance $1 represents the text of the first submatch.
 func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
 	n := 2
@@ -726,7 +726,7 @@ func (re *Regexp) FindSubmatch(b []byte) [][]byte {
 // the submatch with the corresponding index; other names refer to
 // capturing parentheses named with the (?P<name>...) syntax.  A
 // reference to an out of range or unmatched index or a name that is not
-// present in the regular expression is replaced with an empty string.
+// present in the regular expression is replaced with an empty slice.
 // 
 // In the $name form, name is taken to be as long as possible: $1x is
 // equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.

コアとなるコードの解説

上記のdiffは、src/pkg/regexp/regexp.goファイル内の2つのコメント行に対する変更を示しています。

  1. Regexp.ReplaceAllメソッドのコメント (行515):

    • 元のコメント: // with the replacement string repl.
    • 修正後のコメント: // with the replacement text repl.
    • この行は、Regexp.ReplaceAllメソッドが正規表現にマッチした部分を何で置換するかを説明しています。ReplaceAllメソッドのシグネチャはfunc (re *Regexp) ReplaceAll(src, repl []byte) []byteであり、repl引数は[]byte型です。元のコメントでは「string」と記述されていましたが、これはGo言語の型システムにおける「string」型とは異なるため、「text」というより一般的な用語に修正されました。これにより、replがバイトスライスであることをより正確に示し、開発者の誤解を防ぎます。
  2. サブマッチ参照の挙動に関するコメント (行729):

    • 元のコメント: // present in the regular expression is replaced with an empty string.
    • 修正後のコメント: // present in the regular expression is replaced with an empty slice.
    • この行は、正規表現の置換パターン内で$1のようなサブマッチ参照が使用され、その参照が有効なサブマッチに対応しない場合に何が起こるかを説明しています。元のコメントでは「empty string」で置換されると記述されていましたが、実際には空のバイトスライス([]byte{})が使用されます。この修正は、regexpパッケージがバイトスライスを基盤として操作するという事実と整合性を保つためのものです。

これらの変更は、Go言語のドキュメントの品質と正確性を向上させるための、細部へのこだわりを示しています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコード(src/pkg/regexp/regexp.go
  • GitHubのコミット履歴
  • Go言語のIssueトラッカー(Issue #3687に関する直接的なリンクは見つかりませんでしたが、GoのIssueトラッカーで検索することで詳細を確認できる可能性があります。)
    • GoのIssueトラッカーは通常、golang/goリポジトリのIssueセクションで番号を検索することでアクセスできます。