[インデックス 10674] ファイルの概要
このコミットは、Go言語の仕様書(doc/go_spec.html
)における文字リテラルと定数の扱いに関する記述を更新するものです。特に、文字リテラルが「rune」型にデフォルトでなるという挙動を明確にし、型なし定数の変換規則に文字定数を組み込む変更が含まれています。
コミット
commit a933635579355dc152ab0ad6571d92015bb88cb8
Author: Russ Cox <rsc@golang.org>
Date: Thu Dec 8 21:48:19 2011 -0500
spec: var x = 'a' defaults to type rune
R=gri, r, r, adg, iant, ken
CC=golang-dev
https://golang.org/cl/5444053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a933635579355dc152ab0ad6571d92015bb88cb8
元コミット内容
このコミットの元の内容は、Go言語の仕様書において、var x = 'a'
のような文字リテラルがデフォルトで rune
型になることを明確にするものです。これは、文字リテラルが単なる整数定数として扱われるのではなく、より具体的な「文字定数」として認識され、その型推論の挙動が仕様に明記されることを意味します。
変更の背景
Go言語では、当初から文字リテラル(例: 'a'
)はUnicodeコードポイントを表す整数値として扱われていました。しかし、その型推論の挙動や、他の型なし定数との演算における振る舞いが、仕様書上で十分に明確化されていなかった可能性があります。
このコミットが行われた2011年12月は、Go言語がまだ比較的新しい時期であり、言語仕様が活発に議論され、洗練されていく過程でした。特に、型システムと定数の扱いは、言語の堅牢性と使いやすさに直結する重要な要素です。
この変更の背景には、以下の点が考えられます。
- 明確性の向上: 文字リテラルが「整数定数」であるという曖昧な表現から、「文字定数」というより具体的な概念を導入することで、仕様の明確性を高める必要がありました。これにより、開発者が文字リテラルの意味と挙動をより正確に理解できるようになります。
rune
型との整合性: Go言語にはUnicodeコードポイントを扱うための組み込み型であるrune
が存在します。文字リテラルがデフォルトでrune
型になるという挙動を明記することで、文字リテラルとrune
型との間の自然な関連性を強化し、言語の一貫性を保つ狙いがあります。- 型なし定数の一貫した振る舞い: Go言語の型なし定数は、その柔軟性から強力な機能を提供しますが、異なる種類の型なし定数間の演算における型推論の規則は複雑になりがちです。このコミットは、文字定数をこの型なし定数の変換規則に明示的に組み込むことで、より予測可能で一貫した挙動を保証しようとしています。特に、
'w' + 1
のような演算がrune
型の結果を生成することを明確にすることで、開発者の混乱を防ぎます。 - 言語の成熟: 言語が成熟するにつれて、初期の設計では見過ごされがちだった細部の挙動が問題となることがあります。このコミットは、そうした細部の挙動を仕様に落とし込み、言語の安定性と信頼性を高める一環と見なせます。
前提知識の解説
このコミットを理解するためには、Go言語における以下の概念を理解しておく必要があります。
-
文字リテラル (Character Literals): Go言語において、単一引用符 (
'
) で囲まれた文字は文字リテラルと呼ばれます。例えば'a'
,'世'
,'\n'
などです。これらはUnicodeコードポイントを表す整数値として扱われます。 -
rune
型: Go言語には、Unicodeコードポイントを表すために特別に設計された組み込み型rune
があります。rune
はint32
のエイリアスであり、UTF-8でエンコードされた文字列中の1つのUnicode文字(コードポイント)を表現します。Goの文字列はバイトのシーケンスであり、rune
はそのバイトシーケンスからデコードされた論理的な文字単位を扱います。 -
定数 (Constants): Go言語の定数は、コンパイル時に値が決定される不変のエンティティです。定数には、ブーリアン定数、数値定数(整数、浮動小数点、複素数)、文字列定数があります。
-
型なし定数 (Untyped Constants): Go言語の定数には「型なし (untyped)」という概念があります。これは、定数が特定のGoの型(例:
int
,float64
,string
)に関連付けられていない状態を指します。型なし定数は、その値が許容される任意の型に暗黙的に変換される柔軟性を持っています。例えば、型なし整数定数10
は、int
,int32
,float64
など、様々な数値型に代入できます。この柔軟性により、数値演算において型の制約を意識することなく記述できる利点があります。 -
型なし定数の変換規則: 異なる種類の型なし定数間で演算が行われる場合、Go言語には特定の変換規則があります。この規則は、演算結果の型なし定数がどの「種類」になるかを決定します。例えば、型なし整数定数と型なし浮動小数点定数の演算では、結果は型なし浮動小数点定数になります。このコミットは、この規則に「文字定数」を組み込み、その優先順位を明確にしています。
技術的詳細
このコミットは、Go言語の仕様書 doc/go_spec.html
の複数のセクションにわたって変更を加えています。主な変更点は以下の通りです。
-
文字リテラルの定義の変更:
- 以前は「文字リテラルは整数定数を表す」と記述されていましたが、これを「文字リテラルは文字定数を表す」に変更しました。これにより、文字リテラルが単なる数値ではなく、より意味のある「文字」としての定数であることを明確にしています。
-
定数の分類への「文字定数」の追加:
- 定数の種類として、ブーリアン定数、整数定数、浮動小数点定数、複素数定数、文字列定数に加えて、新たに「文字定数 (character constants)」が明示的に追加されました。
- 数値定数の集合(整数、浮動小数点、複素数)に、文字定数も含まれるように記述が変更されました。これにより、文字定数が数値的な性質を持つことが強調されます。
-
型なし定数の変換規則の明確化:
- 最も重要な変更点の一つは、異なる種類の型なし定数間の二項演算における変換規則の更新です。
- 以前は、型なし整数定数と型なし浮動小数点定数の演算に関する特定の規則(整数が浮動小数点に変換される)が記述されていました。
- 新しい規則では、より一般的な原則が導入されました:「二項演算のオペランドが異なる種類の型なし定数である場合、演算と結果は、このリスト(整数、文字、浮動小数点、複素数)で後に出現する種類を使用する。」
- この新しい規則により、例えば型なし整数定数と型なし文字定数の演算では、結果が型なし文字定数になることが明確になります。これは、文字定数が整数定数よりも「後」に位置づけられるためです。
-
例の追加と更新:
- 型なし定数の演算の例に、
const j = 'w' + 1 // j == 'x' (untyped character constant)
という新しい例が追加されました。これは、文字定数と整数定数の演算が文字定数を生成し、その結果が文字として解釈されることを具体的に示しています。 - 既存の例のコメントも、型なし定数の種類をより明確に記述するように更新されました(例:
(floating-point constant)
から(untyped floating-point constant)
)。
- 型なし定数の演算の例に、
-
インターフェース型への代入時の型推論の更新:
- 型なし定数がインターフェース型に代入される際の型推論の規則に、文字定数が
rune
型に変換されるという記述が追加されました。 - 以前は、ブーリアン定数は
bool
、整数定数はint
、浮動小数点定数はfloat64
、複素数定数はcomplex128
、文字列定数はstring
にそれぞれ変換されるとされていましたが、これに「文字定数はrune
」が加わりました。
- 型なし定数がインターフェース型に代入される際の型推論の規則に、文字定数が
これらの変更は、Go言語の型システム、特に定数の振る舞いに関する仕様をより厳密かつ包括的に定義し、開発者が遭遇する可能性のある曖昧さを排除することを目的としています。これにより、コンパイラの挙動がより予測可能になり、Goプログラムの信頼性が向上します。
コアとなるコードの変更箇所
このコミットは、Go言語の仕様書である doc/go_spec.html
ファイルのみを変更しています。
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,5 +1,5 @@
<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of December 5, 2011 -->
+<!-- subtitle Version of December 8, 2011 -->
<!--
TODO
@@ -361,7 +361,7 @@ imaginary_lit = (decimals | float_lit) "i" .
<h3 id="Character_literals">Character literals</h3>
<p>
-A character literal represents an <a href="#Constants">integer constant</a>,
+A character literal represents a <a href="#Constants">character constant</a>,
typically a Unicode code point, as one or more characters enclosed in single
quotes. Within the quotes, any character may appear except single
quote and newline. A single quoted character represents itself,
@@ -513,19 +513,22 @@ literal.
<h2 id="Constants">Constants</h2>
-<p>There are <i>boolean constants</i>, <i>integer constants</i>,
+<p>There are <i>boolean constants</i>,
+<i>character constants</i>,
+<i>integer constants</i>,
<i>floating-point constants</i>, <i>complex constants</i>,
-and <i>string constants</i>. Integer, floating-point,
+and <i>string constants</i>. Character, integer, floating-point,
and complex constants are
collectively called <i>numeric constants</i>.
</p>
<p>
-A constant value is represented by an
+A constant value is represented by a
+<a href="#Character_literals">character</a>,
<a href="#Integer_literals">integer</a>,
<a href="#Floating-point_literals">floating-point</a>,
<a href="#Imaginary_literals">imaginary</a>,
-<a href="#Character_literals">character</a>, or
+or
<a href="#String_literals">string</a> literal,
an identifier denoting a constant,
a <a href="#Constant_expressions">constant expression</a>,
@@ -3412,14 +3415,12 @@ operands and are evaluated at compile-time.\n <p>\n Untyped boolean, numeric, and string constants may be used as operands\n wherever it is legal to use an operand of boolean, numeric, or string type,\n-respectively. Except for shift operations, if the operands of a binary operation\n-are an untyped integer constant and an untyped floating-point constant,\n-the integer constant is converted to an untyped floating-point constant\n-(relevant for <code>/</code> and <code>%</code>).\n-Similarly, untyped integer or floating-point constants may be used as operands\n-wherever it is legal to use an operand of complex type;\n-the integer or floating point constant is converted to a\n-complex constant with a zero imaginary part.\n+respectively.\n+Except for shift operations, if the operands of a binary operation are\n+different kinds of untyped constants, the operation and result use\n+the kind that appears later in this list: integer, character, floating-point, complex.\n+For example, an untyped integer constant divided by an\n+untyped complex constant yields an untyped complex constant.\n </p>\n \n <p>\n@@ -3435,32 +3436,30 @@ complex, or string constant).\n </p>\n \n <pre>\n-const a = 2 + 3.0 // a == 5.0 (floating-point constant)\n-const b = 15 / 4 // b == 3 (integer constant)\n-const c = 15 / 4.0 // c == 3.75 (floating-point constant)\n-const d = 1 << 3.0 // d == 8 (integer constant)\n-const e = 1.0 << 3 // e == 8 (integer constant)\n+const a = 2 + 3.0 // a == 5.0 (untyped floating-point constant)\n+const b = 15 / 4 // b == 3 (untyped integer constant)\n+const c = 15 / 4.0 // c == 3.75 (untyped floating-point constant)\n+const Θ float64 = 3/2 // Θ == 1.5 (type float64)\n+const d = 1 << 3.0 // d == 8 (untyped integer constant)\n+const e = 1.0 << 3 // e == 8 (untyped integer constant)\n const f = int32(1) << 33 // f == 0 (type int32)\n const g = float64(2) >> 1 // illegal (float64(2) is a typed floating-point constant)\n const h = "foo" > "bar" // h == true (type bool)\n+const j = 'w' + 1 // j == 'x' (untyped character constant)\n+const Σ = 1 - 0.707 // (untyped complex constant)\n+const Δ = Σ + 2.0e-4 // (untyped complex constant)\n+const Φ = iota*1i - 1/1i // (untyped complex constant)\n </pre>\n \n <p>\n-Imaginary literals are untyped complex constants (with zero real part)\n-and may be combined in binary\n-operations with untyped integer and floating-point constants; the\n-result is an untyped complex constant.\n-Complex constants are always constructed from\n-constant expressions involving imaginary\n-literals or constants derived from them, or calls of the built-in function\n-<a href=\"#Complex_numbers\"><code>complex</code></a>.\n+Applying the built-in function <code>complex</code> to untyped\n+integer, character, or floating-point constants yields\n+an untyped complex constant.\n </p>\n \n <pre>\n-const Σ = 1 - 0.707i\n-const Δ = Σ + 2.0e-4 - 1/1i\n-const Φ = iota * 1i\n-const iΓ = complex(0, Γ)\n+const ic = complex(0, c) // iΓ == 3.75i (untyped complex constant)\n+const iΘ = complex(0, Θ) // iΘ == 1.5i (type complex128)\n </pre>\n \n <p>\n@@ -3758,10 +3757,10 @@ In assignments, each value must be\n <a href=\"#Assignability\">assignable</a> to the type of the\n operand to which it is assigned. If an untyped <a href=\"#Constants\">constant</a>\n is assigned to a variable of interface type, the constant is <a href=\"#Conversions\">converted</a>\n-to type <code>bool</code>, <code>int</code>, <code>float64</code>,\n+to type <code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>,\n <code>complex128</code> or <code>string</code>\n-respectively, depending on whether the value is a boolean, integer, floating-point,\n-complex, or string constant.\n+respectively, depending on whether the value is a boolean,\n+character, integer, floating-point, complex, or string constant.\n </p>\n \n \n```
## コアとなるコードの解説
このコミットの核心は、Go言語の仕様書における「文字定数」の概念を導入し、その振る舞いを他の型なし定数との関係で明確にすることにあります。
1. **文字リテラルの再定義**:
- `A character literal represents an <a href="#Constants">integer constant</a>,` から `A character literal represents a <a href="#Constants">character constant</a>,` への変更は、文字リテラルが単なる整数値としてではなく、より高レベルな「文字」としての意味を持つ定数であることを強調します。これは、GoがUnicodeを重視し、`rune` 型を導入していることと整合性が取れています。
2. **定数分類の拡張**:
- 定数の種類に `<i>character constants</i>,` が追加され、数値定数のリストにも文字定数が含まれるようになりました。これにより、文字定数がGoの型システムにおいて正式な地位を得たことを示します。
3. **型なし定数の変換規則の一般化**:
- 以前の仕様では、型なし整数と浮動小数点、または整数/浮動小数点と複素数の間の特定の変換規則が記述されていました。
- 新しい規則 `if the operands of a binary operation are different kinds of untyped constants, the operation and result use the kind that appears later in this list: integer, character, floating-point, complex.` は、より包括的で一般的な規則を導入しています。このリストの順序は、変換の優先順位を示しており、より「広い」範囲をカバーする型なし定数に変換されることを意味します。
- `integer` (整数)
- `character` (文字)
- `floating-point` (浮動小数点)
- `complex` (複素数)
- この順序により、例えば `integer` と `character` の演算では `character` に、`character` と `floating-point` の演算では `floating-point` に、といった形で結果の型なし定数の種類が決定されます。
4. **`const j = 'w' + 1` の例**:
- この新しい例は、文字定数と整数定数の加算がどのように処理されるかを具体的に示しています。`'w'` は文字定数、`1` は整数定数です。上記の新しい変換規則に従い、`character` が `integer` よりもリストで後に出現するため、結果は型なし文字定数になります。`'w'` のUnicodeコードポイントに `1` が加算され、その結果が新しい文字定数 `'x'` として表現されます。これは、文字リテラルが単なる数値としてではなく、文字としての意味を持つことを裏付けています。
5. **インターフェース型への代入時の `rune` への変換**:
- `to type <code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>, <code>complex128</code> or <code>string</code>` の変更は、型なし文字定数がインターフェース型に代入される際に、デフォルトで `rune` 型に変換されることを明示しています。これは、文字リテラルが `rune` 型と密接に関連していることを強調し、Goの型システムにおける `rune` の役割を強化します。
これらの変更は、Go言語の定数と型システムのセマンティクスをより厳密に定義し、特に文字リテラルの振る舞いを明確にすることで、開発者がより正確で予測可能なコードを書けるように貢献しています。
## 関連リンク
- Go言語の仕様書: [https://go.dev/ref/spec](https://go.dev/ref/spec)
- Go言語の `rune` 型に関する公式ドキュメント: [https://go.dev/blog/strings](https://go.dev/blog/strings) (Strings, bytes, runes, and characters in Go)
## 参考にした情報源リンク
- Go言語の公式ドキュメントと仕様書
- Go言語のコミット履歴 (GitHub)
- Go言語の型なし定数に関する一般的な解説記事 (Web検索)
- Go言語の `rune` 型に関する解説記事 (Web検索)
# [インデックス 10674] ファイルの概要
このコミットは、Go言語の仕様書(`doc/go_spec.html`)における文字リテラルと定数の扱いに関する記述を更新するものです。特に、文字リテラルが「rune」型にデフォルトでなるという挙動を明確にし、型なし定数の変換規則に文字定数を組み込む変更が含まれています。これにより、Go言語の型システムにおける文字定数の振る舞いがより厳密かつ包括的に定義され、開発者が遭遇する可能性のある曖昧さを排除することを目的としています。
## コミット
commit a933635579355dc152ab0ad6571d92015bb88cb8 Author: Russ Cox rsc@golang.org Date: Thu Dec 8 21:48:19 2011 -0500
spec: var x = 'a' defaults to type rune
R=gri, r, r, adg, iant, ken
CC=golang-dev
https://golang.org/cl/5444053
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/a933635579355dc152ab0ad6571d92015bb88cb8](https://github.com/golang/go/commit/a933635579355dc152ab0ad6571d92015bb88cb8)
## 元コミット内容
このコミットの元の内容は、Go言語の仕様書において、`var x = 'a'` のような文字リテラルがデフォルトで `rune` 型になることを明確にするものです。これは、文字リテラルが単なる整数定数として扱われるのではなく、より具体的な「文字定数」として認識され、その型推論の挙動が仕様に明記されることを意味します。
## 変更の背景
Go言語では、当初から文字リテラル(例: `'a'`)はUnicodeコードポイントを表す整数値として扱われていました。しかし、その型推論の挙動や、他の型なし定数との演算における振る舞いが、仕様書上で十分に明確化されていなかった可能性があります。
このコミットが行われた2011年12月は、Go言語がまだ比較的新しい時期であり、言語仕様が活発に議論され、洗練されていく過程でした。特に、型システムと定数の扱いは、言語の堅牢性と使いやすさに直結する重要な要素です。
この変更の背景には、以下の点が考えられます。
1. **明確性の向上**: 文字リテラルが「整数定数」であるという曖昧な表現から、「文字定数」というより具体的な概念を導入することで、仕様の明確性を高める必要がありました。これにより、開発者が文字リテラルの意味と挙動をより正確に理解できるようになります。
2. **`rune` 型との整合性**: Go言語にはUnicodeコードポイントを扱うための組み込み型である `rune` が存在します。文字リテラルがデフォルトで `rune` 型になるという挙動を明記することで、文字リテラルと `rune` 型との間の自然な関連性を強化し、言語の一貫性を保つ狙いがあります。
3. **型なし定数の一貫した振る舞い**: Go言語の型なし定数は、その柔軟性から強力な機能を提供しますが、異なる種類の型なし定数間の演算における型推論の規則は複雑になりがちです。このコミットは、文字定数をこの型なし定数の変換規則に明示的に組み込むことで、より予測可能で一貫した挙動を保証しようとしています。特に、`'w' + 1` のような演算が `rune` 型の結果を生成することを明確にすることで、開発者の混乱を防ぎます。
4. **言語の成熟**: 言語が成熟するにつれて、初期の設計では見過ごされがちだった細部の挙動が問題となることがあります。このコミットは、そうした細部の挙動を仕様に落とし込み、言語の安定性と信頼性を高める一環と見なせます。
## 前提知識の解説
このコミットを理解するためには、Go言語における以下の概念を理解しておく必要があります。
1. **文字リテラル (Character Literals)**:
Go言語において、単一引用符 (`'`) で囲まれた文字は文字リテラルと呼ばれます。例えば `'a'`, `'ä'`, `'\n'` などです。これらはUnicodeコードポイントを表す整数値として扱われます。GoのソースコードはUTF-8でエンコードされたUnicodeテキストであり、文字リテラルは単一のUnicodeコードポイントを表します。
2. **`rune` 型**:
Go言語には、Unicodeコードポイントを表すために特別に設計された組み込み型 `rune` があります。`rune` は `int32` のエイリアスであり、UTF-8でエンコードされた文字列中の1つのUnicode文字(コードポイント)を表現します。Goの文字列はバイトのシーケンスであり、`rune` はそのバイトシーケンスからデコードされた論理的な文字単位を扱います。
3. **定数 (Constants)**:
Go言語の定数は、コンパイル時に値が決定される不変のエンティティです。定数には、ブーリアン定数、数値定数(整数、浮動小数点、複素数)、文字列定数があります。
4. **型なし定数 (Untyped Constants)**:
Go言語の定数には「型なし (untyped)」という概念があります。これは、定数が特定のGoの型(例: `int`, `float64`, `string`)に関連付けられていない状態を指します。型なし定数は、その値が許容される任意の型に暗黙的に変換される柔軟性を持っています。例えば、型なし整数定数 `10` は、`int`, `int32`, `float64` など、様々な数値型に代入できます。この柔軟性により、数値演算において型の制約を意識することなく記述できる利点があります。
5. **型なし定数の変換規則**:
異なる種類の型なし定数間で演算が行われる場合、Go言語には特定の変換規則があります。この規則は、演算結果の型なし定数がどの「種類」になるかを決定します。例えば、型なし整数定数と型なし浮動小数点定数の演算では、結果は型なし浮動小数点定数になります。このコミットは、この規則に「文字定数」を組み込み、その優先順位を明確にしています。
## 技術的詳細
このコミットは、Go言語の仕様書 `doc/go_spec.html` の複数のセクションにわたって変更を加えています。主な変更点は以下の通りです。
1. **文字リテラルの定義の変更**:
- 以前は「文字リテラルは整数定数を表す」と記述されていましたが、これを「文字リテラルは文字定数を表す」に変更しました。これにより、文字リテラルが単なる数値ではなく、より意味のある「文字」としての定数であることを明確にしています。
2. **定数の分類への「文字定数」の追加**:
- 定数の種類として、ブーリアン定数、整数定数、浮動小数点定数、複素数定数、文字列定数に加えて、新たに「文字定数 (character constants)」が明示的に追加されました。
- 数値定数の集合(整数、浮動小数点、複素数)に、文字定数も含まれるように記述が変更されました。これにより、文字定数が数値的な性質を持つことが強調されます。
3. **型なし定数の変換規則の明確化**:
- 最も重要な変更点の一つは、異なる種類の型なし定数間の二項演算における変換規則の更新です。
- 以前は、型なし整数定数と型なし浮動小数点定数の演算に関する特定の規則(整数が浮動小数点に変換される)が記述されていました。
- 新しい規則では、より一般的な原則が導入されました:「二項演算のオペランドが異なる種類の型なし定数である場合、演算と結果は、このリスト(整数、文字、浮動小数点、複素数)で後に出現する種類を使用する。」
- この新しい規則により、例えば型なし整数定数と型なし文字定数の演算では、結果が型なし文字定数になることが明確になります。これは、文字定数が整数定数よりも「後」に位置づけられるためです。
4. **例の追加と更新**:
- 型なし定数の演算の例に、`const j = 'w' + 1 // j == 'x' (untyped character constant)` という新しい例が追加されました。これは、文字定数と整数定数の演算が文字定数を生成し、その結果が文字として解釈されることを具体的に示しています。
- 既存の例のコメントも、型なし定数の種類をより明確に記述するように更新されました(例: `(floating-point constant)` から `(untyped floating-point constant)`)。
5. **インターフェース型への代入時の型推論の更新**:
- 型なし定数がインターフェース型に代入される際の型推論の規則に、文字定数が `rune` 型に変換されるという記述が追加されました。
- 以前は、ブーリアン定数は `bool`、整数定数は `int`、浮動小数点定数は `float64`、複素数定数は `complex128`、文字列定数は `string` にそれぞれ変換されるとされていましたが、これに「文字定数は `rune`」が加わりました。
これらの変更は、Go言語の型システム、特に定数の振る舞いに関する仕様をより厳密かつ包括的に定義し、開発者が遭遇する可能性のある曖昧さを排除することを目的としています。これにより、コンパイラの挙動がより予測可能になり、Goプログラムの信頼性が向上します。
## コアとなるコードの変更箇所
このコミットは、Go言語の仕様書である `doc/go_spec.html` ファイルのみを変更しています。
```diff
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,5 +1,5 @@
<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of December 5, 2011 -->
+<!-- subtitle Version of December 8, 2011 -->
<!--
TODO
@@ -361,7 +361,7 @@ imaginary_lit = (decimals | float_lit) "i" .
<h3 id="Character_literals">Character literals</h3>
<p>
-A character literal represents an <a href="#Constants">integer constant</a>,
+A character literal represents a <a href="#Constants">character constant</a>,
typically a Unicode code point, as one or more characters enclosed in single
quotes. Within the quotes, any character may appear except single
quote and newline. A single quoted character represents itself,
@@ -513,19 +513,22 @@ literal.
<h2 id="Constants">Constants</h2>
-<p>There are <i>boolean constants</i>, <i>integer constants</i>,
+<p>There are <i>boolean constants</i>,
+<i>character constants</i>,
+<i>integer constants</i>,
<i>floating-point constants</i>, <i>complex constants</i>,
-and <i>string constants</i>. Integer, floating-point,
+and <i>string constants</i>. Character, integer, floating-point,
and complex constants are
collectively called <i>numeric constants</i>.
</p>
<p>
-A constant value is represented by an
+A constant value is represented by a
+<a href="#Character_literals">character</a>,
<a href="#Integer_literals">integer</a>,
<a href="#Floating-point_literals">floating-point</a>,
<a href="#Imaginary_literals">imaginary</a>,
-<a href="#Character_literals">character</a>, or
+or
<a href="#String_literals">string</a> literal,
an identifier denoting a constant,
a <a href="#Constant_expressions">constant expression</a>,
@@ -3412,14 +3415,12 @@ operands and are evaluated at compile-time.\n <p>\n Untyped boolean, numeric, and string constants may be used as operands\n wherever it is legal to use an operand of boolean, numeric, or string type,\n-respectively. Except for shift operations, if the operands of a binary operation\n-are an untyped integer constant and an untyped floating-point constant,\n-the integer constant is converted to an untyped floating-point constant\n-(relevant for <code>/</code> and <code>%</code>).\n-Similarly, untyped integer or floating-point constants may be used as operands\n-wherever it is legal to use an operand of complex type;\n-the integer or floating point constant is converted to a\n-complex constant with a zero imaginary part.\n+respectively.\n+Except for shift operations, if the operands of a binary operation are\n+different kinds of untyped constants, the operation and result use\n+the kind that appears later in this list: integer, character, floating-point, complex.\n+For example, an untyped integer constant divided by an\n+untyped complex constant yields an untyped complex constant.\n </p>\n \n <p>\n@@ -3435,32 +3436,30 @@ complex, or string constant).\n </p>\n \n <pre>\n-const a = 2 + 3.0 // a == 5.0 (floating-point constant)\n-const b = 15 / 4 // b == 3 (integer constant)\n-const c = 15 / 4.0 // c == 3.75 (floating-point constant)\n-const d = 1 << 3.0 // d == 8 (integer constant)\n-const e = 1.0 << 3 // e == 8 (integer constant)\n+const a = 2 + 3.0 // a == 5.0 (untyped floating-point constant)\n+const b = 15 / 4 // b == 3 (untyped integer constant)\n+const c = 15 / 4.0 // c == 3.75 (untyped floating-point constant)\n+const Θ float64 = 3/2 // Θ == 1.5 (type float64)\n+const d = 1 << 3.0 // d == 8 (untyped integer constant)\n+const e = 1.0 << 3 // e == 8 (untyped integer constant)\n const f = int32(1) << 33 // f == 0 (type int32)\n const g = float64(2) >> 1 // illegal (float64(2) is a typed floating-point constant)\n const h = "foo" > "bar" // h == true (type bool)\n+const j = 'w' + 1 // j == 'x' (untyped character constant)\n+const Σ = 1 - 0.707 // (untyped complex constant)\n+const Δ = Σ + 2.0e-4 // (untyped complex constant)\n+const Φ = iota*1i - 1/1i // (untyped complex constant)\n </pre>\n \n <p>\n-Imaginary literals are untyped complex constants (with zero real part)\n-and may be combined in binary\n-operations with untyped integer and floating-point constants; the\n-result is an untyped complex constant.\n-Complex constants are always constructed from\n-constant expressions involving imaginary\n-literals or constants derived from them, or calls of the built-in function\n-<a href=\"#Complex_numbers\"><code>complex</code></a>.\n+Applying the built-in function <code>complex</code> to untyped\n+integer, character, or floating-point constants yields\n+an untyped complex constant.\n </p>\n \n <pre>\n-const Σ = 1 - 0.707i\n-const Δ = Σ + 2.0e-4 - 1/1i\n-const Φ = iota * 1i\n-const iΓ = complex(0, Γ)\n+const ic = complex(0, c) // iΓ == 3.75i (untyped complex constant)\n+const iΘ = complex(0, Θ) // iΘ == 1.5i (type complex128)\n </pre>\n \n <p>\n@@ -3758,10 +3757,10 @@ In assignments, each value must be\n <a href=\"#Assignability\">assignable</a> to the type of the\n operand to which it is assigned. If an untyped <a href=\"#Constants\">constant</a>\n is assigned to a variable of interface type, the constant is <a href=\"#Conversions\">converted</a>\n-to type <code>bool</code>, <code>int</code>, <code>float64</code>,\n+to type <code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>,\n <code>complex128</code> or <code>string</code>\n-respectively, depending on whether the value is a boolean, integer, floating-point,\n-complex, or string constant.\n+respectively, depending on whether the value is a boolean,\n+character, integer, floating-point, complex, or string constant.\n </p>\n \n \n```
## コアとなるコードの解説
このコミットの核心は、Go言語の仕様書における「文字定数」の概念を導入し、その振る舞いを他の型なし定数との関係で明確にすることにあります。
1. **文字リテラルの再定義**:
- `A character literal represents an <a href="#Constants">integer constant</a>,` から `A character literal represents a <a href="#Constants">character constant</a>,` への変更は、文字リテラルが単なる整数値としてではなく、より高レベルな「文字」としての意味を持つ定数であることを強調します。これは、GoがUnicodeを重視し、`rune` 型を導入していることと整合性が取れています。
2. **定数分類の拡張**:
- 定数の種類に `<i>character constants</i>,` が追加され、数値定数のリストにも文字定数が含まれるようになりました。これにより、文字定数がGoの型システムにおいて正式な地位を得たことを示します。
3. **型なし定数の変換規則の一般化**:
- 以前の仕様では、型なし整数と浮動小数点、または整数/浮動小数点と複素数の間の特定の変換規則が記述されていました。
- 新しい規則 `if the operands of a binary operation are different kinds of untyped constants, the operation and result use the kind that appears later in this list: integer, character, floating-point, complex.` は、より包括的で一般的な規則を導入しています。このリストの順序は、変換の優先順位を示しており、より「広い」範囲をカバーする型なし定数に変換されることを意味します。
- `integer` (整数)
- `character` (文字)
- `floating-point` (浮動小数点)
- `complex` (複素数)
- この順序により、例えば `integer` と `character` の演算では `character` に、`character` と `floating-point` の演算では `floating-point` に、といった形で結果の型なし定数の種類が決定されます。
4. **`const j = 'w' + 1` の例**:
- この新しい例は、文字定数と整数定数の加算がどのように処理されるかを具体的に示しています。`'w'` は文字定数、`1` は整数定数です。上記の新しい変換規則に従い、`character` が `integer` よりもリストで後に出現するため、結果は型なし文字定数になります。`'w'` のUnicodeコードポイントに `1` が加算され、その結果が新しい文字定数 `'x'` として表現されます。これは、文字リテラルが単なる数値としてではなく、文字としての意味を持つことを裏付けています。
5. **インターフェース型への代入時の `rune` への変換**:
- `to type <code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>, <code>complex128</code> or <code>string</code>` の変更は、型なし文字定数がインターフェース型に代入される際に、デフォルトで `rune` 型に変換されることを明示しています。これは、文字リテラルが `rune` 型と密接に関連していることを強調し、Goの型システムにおける `rune` の役割を強化します。
これらの変更は、Go言語の定数と型システムのセマンティクスをより厳密に定義し、特に文字リテラルの振る舞いを明確にすることで、開発者がより正確で予測可能なコードを書けるように貢献しています。
## 関連リンク
- Go言語の仕様書: [https://go.dev/ref/spec](https://go.dev/ref/spec)
- Go言語の `rune` 型に関する公式ドキュメント: [https://go.dev/blog/strings](https://go.dev/blog/strings) (Strings, bytes, runes, and characters in Go)
## 参考にした情報源リンク
- Go言語の公式ドキュメントと仕様書
- Go言語のコミット履歴 (GitHub)
- Web検索: "Go language specification character literals untyped constants conversion rules"