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

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

このコミットは、Go言語の標準ライブラリstrconvパッケージ内のQuoteRuneおよび関連する関数(QuoteRuneToASCII, AppendQuoteRune, AppendQuoteRuneToASCII)の引数型をintからruneに変更するものです。これにより、これらの関数がよりGo言語のイディオムに沿った形でルーン(Unicodeコードポイント)を扱うようになります。

コミット

commit 38df0459ae1631e223edbe2c9f1a970bbb994fe9
Author: Rob Pike <r@golang.org>
Date:   Tue Dec 13 11:13:23 2011 -0800

    strconv: make QuoteRune etc. take a rune argument
    Just an oversight it didn't already.
    Fixes #2515.
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/5483064

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

https://github.com/golang/go/commit/38df0459ae1631e223edbe2c9f1a970bbb994fe9

元コミット内容

strconv: make QuoteRune etc. take a rune argument Just an oversight it didn't already. Fixes #2515.

変更の背景

この変更は、Go言語のstrconvパッケージにあるQuoteRuneおよび関連関数が、ルーンを扱うにもかかわらず、その引数型がintであったという「見落とし」を修正するために行われました。コミットメッセージにあるFixes #2515が示す通り、これはGoのIssue 2515に対応するものです。

GoのIssue 2515は、「strconv: QuoteRune should take rune argument」というタイトルで、QuoteRune関数がintではなくrune型の引数を取るべきであるという提案でした。Go言語では、Unicodeコードポイントを表すために組み込み型runeが導入されており、これは実質的にint32のエイリアスですが、そのセマンティクスは文字を表すことに特化しています。したがって、ルーンを引用符で囲む(クォートする)関数がintを引数として受け取るのは、Goの型システムとイディオムにそぐわないと判断されました。この変更は、APIの一貫性と明確性を向上させることを目的としています。

前提知識の解説

Go言語におけるrune

Go言語において、runeはUnicodeコードポイントを表す組み込み型です。これはint32のエイリアスとして定義されており、Goの文字列がUTF-8でエンコードされたバイト列であるのに対し、runeは個々のUnicode文字(コードポイント)を表現します。例えば、'A'rune型のリテラルであり、その値は65(ASCIIコード)です。日本語の文字などもruneとして扱われます。

strconvパッケージ

strconvパッケージは、Go言語において基本的なデータ型(文字列、整数、浮動小数点数、真偽値など)と文字列との間の変換機能を提供します。例えば、文字列を整数に変換するAtoiや、整数を文字列に変換するItoaなどがあります。

strconv.QuoteRuneおよび関連関数

strconv.QuoteRune関数は、与えられたルーンをGoの文字リテラル形式(シングルクォートで囲み、必要に応じてエスケープシーケンスを使用)の文字列に変換します。例えば、QuoteRune('A')"'A'"を返します。QuoteRuneToASCIIは、非ASCII文字もASCIIエスケープシーケンス(例: \uXXXX)に変換して引用符で囲みます。AppendQuoteRuneおよびAppendQuoteRuneToASCIIは、これらの結果を既存のバイトスライスに追加する関数です。

これらの関数は、デバッグ出力、ログ記録、またはGoのソースコード生成など、ルーンを人間が読める形式やGoの構文に準拠した形式で表現する必要がある場合に利用されます。

技術的詳細

このコミットの技術的な詳細は、主にGo言語の型システムとAPI設計の観点から理解できます。

  1. 型の一貫性: 変更前は、QuoteRuneなどの関数はintを引数として受け取っていました。Goではruneint32のエイリアスであるため、技術的にはint(通常はintは32ビットまたは64ビットの整数型)でルーンの値を渡すことは可能でした。しかし、これはセマンティックな不一致を生じさせます。関数が「ルーンをクォートする」という目的を持っているにもかかわらず、汎用的な整数型を受け取ることで、開発者が意図しない整数値を渡してしまう可能性がありました。rune型を明示的に引数とすることで、関数の意図がより明確になり、コンパイラによる型チェックの恩恵を受けることができます。

  2. 可読性と意図の明確化: コードを読む際、func QuoteRune(r rune) stringと書かれている方が、この関数がUnicodeコードポイントを扱うものであることが一目で理解できます。func QuoteRune(i int) stringでは、iが単なる整数なのか、それともルーンとして解釈されるべきものなのかが不明瞭になります。

  3. fmtパッケージへの影響: fmtパッケージは、Goのフォーマット済みI/Oを扱うためのパッケージです。このコミットでは、fmtパッケージ内のfmt_qc関数がstrconv.QuoteRuneおよびstrconv.QuoteRuneToASCIIを呼び出す際に、int64型の引数crune(c)と明示的に型変換して渡すように変更されています。これは、strconvパッケージの関数のシグネチャ変更に対応するための修正であり、fmtパッケージがstrconvパッケージの新しいAPIに準拠するように更新されたことを示しています。

この変更は、Go言語のAPIが、その設計思想である「明確性」と「安全性」を追求する過程の一環として行われたものです。

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

diff --git a/src/pkg/fmt/format.go b/src/pkg/fmt/format.go
index fbafa9d9ad..5f62c067f0 100644
--- a/src/pkg/fmt/format.go
+++ b/src/pkg/fmt/format.go
@@ -331,9 +331,9 @@ func (f *fmt) fmt_q(s string) {
 func (f *fmt) fmt_qc(c int64) {
 	var quoted string
 	if f.plus {
-		quoted = strconv.QuoteRuneToASCII(int(c))
+		quoted = strconv.QuoteRuneToASCII(rune(c))
 	} else {
-		quoted = strconv.QuoteRune(int(c))
+		quoted = strconv.QuoteRune(rune(c))
 	}\n \tf.padString(quoted)\n }\ndiff --git a/src/pkg/strconv/quote.go b/src/pkg/strconv/quote.go\nindex 30b384df8e..edba62954b 100644
--- a/src/pkg/strconv/quote.go
+++ b/src/pkg/strconv/quote.go
@@ -116,30 +116,30 @@ func AppendQuoteToASCII(dst []byte, s string) []byte {
 // rune.  The returned string uses Go escape sequences (\\t, \\n, \\xFF, \\u0100)\n // for control characters and non-printable characters as defined by\n // unicode.IsPrint.\n-func QuoteRune(rune int) string {\n+func QuoteRune(r rune) string {\n \t// TODO: avoid the allocation here.\n-\treturn quoteWith(string(rune), \'\\\'\', false)\n+\treturn quoteWith(string(r), \'\\\'\', false)\n }\n \n // AppendQuoteRune appends a single-quoted Go character literal representing the rune,\n // as generated by QuoteRune, to dst and returns the extended buffer.\n-func AppendQuoteRune(dst []byte, rune int) []byte {\n-\treturn append(dst, QuoteRune(rune)...)\n+func AppendQuoteRune(dst []byte, r rune) []byte {\n+\treturn append(dst, QuoteRune(r)...)\n }\n \n // QuoteRuneToASCII returns a single-quoted Go character literal representing\n // the rune.  The returned string uses Go escape sequences (\\t, \\n, \\xFF,\n // \\u0100) for non-ASCII characters and non-printable characters as defined\n // by unicode.IsPrint.\n-func QuoteRuneToASCII(rune int) string {\n+func QuoteRuneToASCII(r rune) string {\n \t// TODO: avoid the allocation here.\n-\treturn quoteWith(string(rune), \'\\\'\', true)\n+\treturn quoteWith(string(r), \'\\\'\', true)\n }\n \n // AppendQuoteRune appends a single-quoted Go character literal representing the rune,\n // as generated by QuoteRuneToASCII, to dst and returns the extended buffer.\n-func AppendQuoteRuneToASCII(dst []byte, rune int) []byte {\n-\treturn append(dst, QuoteRuneToASCII(rune)...)\n+func AppendQuoteRuneToASCII(dst []byte, r rune) []byte {\n+\treturn append(dst, QuoteRuneToASCII(r)...)\n }\n \n // CanBackquote returns whether the string s would be\ndiff --git a/src/pkg/strconv/quote_test.go b/src/pkg/strconv/quote_test.go\nindex e440797162..419943d83c 100644
--- a/src/pkg/strconv/quote_test.go
+++ b/src/pkg/strconv/quote_test.go
@@ -47,7 +47,7 @@ func TestQuoteToASCII(t *testing.T) {\n }\n \n type quoteRuneTest struct {\n-\tin    int\n+\tin    rune\n \tout   string\n \tascii string\n }\n```

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

このコミットは、主に`src/pkg/strconv/quote.go`と`src/pkg/fmt/format.go`、そしてテストファイル`src/pkg/strconv/quote_test.go`の3つのファイルに影響を与えています。

1.  **`src/pkg/strconv/quote.go`の変更**:
    *   `QuoteRune(rune int) string` が `QuoteRune(r rune) string` に変更されました。引数名も`rune`から`r`に変わっていますが、最も重要なのは型が`int`から`rune`になった点です。
    *   同様に、`AppendQuoteRune(dst []byte, rune int) []byte` が `AppendQuoteRune(dst []byte, r rune) []byte` に、`QuoteRuneToASCII(rune int) string` が `QuoteRuneToASCII(r rune) string` に、`AppendQuoteRuneToASCII(dst []byte, rune int) []byte` が `AppendQuoteRuneToASCII(dst []byte, r rune) []byte` にそれぞれ変更されています。
    *   これらの関数内部での`string(rune)`や`QuoteRune(rune)`といった呼び出しも、新しい引数名`r`に合わせて`string(r)`や`QuoteRune(r)`に変更されています。これは、引数として受け取った`rune`型の値をそのまま利用することを意味します。

2.  **`src/pkg/fmt/format.go`の変更**:
    *   `fmt`パッケージ内の`fmt_qc`関数は、`strconv.QuoteRuneToASCII`と`strconv.QuoteRune`を呼び出していました。
    *   変更前は、`int64`型の引数`c`を`int(c)`と型変換して`strconv`の関数に渡していました。
    *   変更後は、`strconv`の関数の引数型が`rune`になったため、`rune(c)`と明示的に`rune`型に変換して渡すように修正されました。これは、`fmt`パッケージが`strconv`パッケージのAPI変更に追従するための必要な修正です。

3.  **`src/pkg/strconv/quote_test.go`の変更**:
    *   テスト構造体`quoteRuneTest`のフィールド`in`の型が`int`から`rune`に変更されました。これは、テストケースが新しい関数シグネチャに合わせて`rune`型の値を渡すように更新されたことを示しています。

これらの変更は全体として、`strconv`パッケージのルーンを扱う関数が、Go言語の`rune`型を直接引数として受け取るようにすることで、APIのセマンティクスをより正確にし、型安全性を向上させることを目的としています。

## 関連リンク

*   Go Issue 2515: [https://github.com/golang/go/issues/2515](https://github.com/golang/go/issues/2515)
*   Go Change List 5483064: [https://golang.org/cl/5483064](https://golang.org/cl/5483064)

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

*   Web search results for "Go issue 2515":
    *   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHcN5ew7-HGrzvfuY45GTL0jCjPKkvPWRCDUnKtUDL4KFVM84EpSSX85qUm_aH7hWsfpezyBsA9iadwN5uWWpBf-Ul6Ixi8-2S4uZUhteAs90hLvQ8_W-0Bq3pu73_fzkViqA==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHcN5ew7-HGrzvfuY45GTL0jCjPKkvPWRCDUnKtUDL4KFVM84EpSSX85qUm_aH7hWsfpezyBsA9iadwN5uWWpBf-Ul6Ixi8-2S4uZUhteAs90hLvQ8_W-0Bq3pu73_fzkViqA==)
    *   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGKgimmTQRSuDeIf_PLCB3GYn92wfNlZdqo4h51WU_coyt5Kh4gF9BuOY1SiAyvvwcl7VJsCqo0oBEaGAwHRdFbaPFg_ac3yJ2zYyOdpu3wwZRPdPCvvk5DSfTfP6Eu_H1xyssIkoP-EjKcTaleJH8=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGKgimmTQRSuDeIf_PLCB3GYn92wfNlZdqo4h51WU_coyt5Kh4gF9BuOY1SiAyvvwcl7VJsCqo0oBEaGAwHRdFbaPFg_ac3yJ2zYyOdpu3wwZRPdPCvvk5DSfTfP6Eu_H1xyssIkoP-EjKcTaleJH8=)
    *   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHsmfOVqxzwFntSZrgl2sf62azI7rWdQRnWQ4xv5YQ7Er8u-ow72b0t5Zw8RgIwM9x2kX-fo9_6vN6hy7FeQo8Rutd9NgPWTKfQhWraQT1Ys_D7qA-gPeQYVCCkbczd](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHsmfOVqxzwFntSZrgl2sf62azI7rWdQRnWQ4xv5YQ7Er8u-ow72b0t5Zw8RgIwM9x2kX-fo9_6vN6hy7FeQo8Rutd9NgPWTKfQhWraQT1Ys_D7qA-gPeQYVCCkbczd)
    *   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGkux82V5UXgrKEMA9s_N7ooxqssfBVbRUKl51rQryi7F2rITLCynC0zIdt-mVRsYFalYiZzCNZ2W3YmobvzFHJivvBVGTZ_E8SeuH6lkr_q6lMGl54LSYcXPkcCx9cubz1cR_JfVfJaahAF8Vje6qM=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGkux82V5UXgrKEMA9s_N7ooxqssfBVbRUKl51rQryi7F2rITLCynC0zIdt-mVRsYFalYiZzCNZ2W3YmobvzFHJivvBVGTZ_E8SeuH6lkr_q6lMGl54LSYcXPkcCx9cubz1cR_JfVfJaahAF8Vje6qM=)