[インデックス 10598] ファイルの概要
このコミットは、Go言語の仕様書 (doc/go_spec.html
) に対する変更であり、複合リテラル (composite literal) の短縮記法に関する記述を更新しています。具体的には、Go 1 リリース計画の一環として、複合リテラル内で型を省略できる新たなケースが追加されました。これにより、コードの記述がより簡潔になります。
コミット
commit 5f49456465f53f96bee03ac8cbe0d564e31576c2
Author: Russ Cox <rsc@golang.org>
Date: Fri Dec 2 14:12:53 2011 -0500
spec: additional composite literal shortenings per Go 1 plan
R=golang-dev, gri, r, r
CC=golang-dev
https://golang.org/cl/5449067
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5f49456465f53f96bee03ac8cbe0d564e31576c2
元コミット内容
spec: additional composite literal shortenings per Go 1 plan
R=golang-dev, gri, r, r
CC=golang-dev
https://golang.org/cl/5449067
変更の背景
この変更は、Go言語のバージョン1 (Go 1) のリリース計画の一部として行われました。Go 1は、Go言語の安定版としての最初のメジャーリリースであり、言語仕様の安定化と互換性の保証を目的としていました。このコミットは、その安定化プロセスの中で、複合リテラルの記述をより簡潔にするための改善提案が採用された結果です。
Go言語では、配列、スライス、マップ、構造体などの複合型を初期化する際に「複合リテラル」を使用します。初期のGo言語では、ネストされた複合リテラルにおいて、内部の型を明示的に記述する必要がありました。しかし、これは冗長であり、コードの可読性を損なう可能性がありました。Go 1の目標の一つは、言語をより使いやすく、効率的にすることであったため、このような冗長性を排除する方向で仕様が検討されました。
このコミットで導入された短縮記法は、特にポインタ型や構造体のフィールド初期化において、開発者がより自然にコードを記述できるようにすることを意図しています。これにより、コードの記述量が減り、視覚的なノイズが少なくなることで、コードの意図がより明確に伝わるようになります。
前提知識の解説
複合リテラル (Composite Literals)
Go言語における複合リテラルは、配列、スライス、マップ、構造体といった複合型の値を直接構築するための構文です。これらは、型名とそれに続く波括弧 {}
で囲まれた要素のリストで構成されます。
例:
- 配列リテラル:
[3]int{1, 2, 3}
- スライスリテラル:
[]int{1, 2, 3}
- マップリテラル:
map[string]int{"a": 1, "b": 2}
- 構造体リテラル:
struct { X, Y int }{X: 10, Y: 20}
型の省略 (Elision)
Go言語では、コンテキストから型が推論できる場合に、型の記述を省略できる「型の省略 (type elision)」という機能があります。例えば、変数の宣言時に初期値がある場合、型を明示的に書かなくてもコンパイラが型を推論します (var x = 10
は var x int = 10
と同じ)。
複合リテラルにおいても、ネストされた複合リテラルの要素の型が、親の複合リテラルの要素型と同一である場合、その型を省略できるというルールが既に存在していました。
例:
[][]int{{1, 2}, {3, 4}}
は、[][]int{[]int{1, 2}, []int{3, 4}}
と同じ意味です。内側のスライスリテラル []int
の型が、外側のスライス [][]int
の要素型 []int
と同じであるため、省略可能です。
Go 1計画
Go 1は、2012年3月にリリースされたGo言語の最初のメジャーバージョンです。Go 1の主な目的は、言語仕様、標準ライブラリ、およびツールチェインを安定させ、将来のバージョンとの後方互換性を保証することでした。これにより、Go言語で書かれたプログラムが、将来のGoバージョンでも変更なしに動作することが期待されました。この安定化プロセスの中で、言語の使いやすさや表現力を向上させるための細かな調整も行われました。複合リテラルの短縮記法の追加も、その一環です。
技術的詳細
このコミットは、Go言語仕様書 (doc/go_spec.html
) の「Composite literals」セクションに、複合リテラルにおける型の省略に関する新たなルールを追加しています。
既存のルールでは、配列、スライス、マップ型の複合リテラル内で、要素がそれ自体複合リテラルであり、その型が親の要素型と同一である場合に型を省略できるとされていました。
このコミットによって、以下の2つの新しい短縮記法が追加されました。
-
ポインタ型要素の複合リテラルにおける
&T
の省略: 要素の型がポインタ型 (*T
) である場合、その要素が複合リテラルのアドレス (&T{...}
) であるならば、&T
の部分を省略できるようになりました。つまり、&T{...}
の代わりに{...}
と記述できます。コンパイラは、要素の型がポインタ型であることから、自動的にアドレス演算子&
と基底型T
を補完します。例:
[...]*Point{{1.5, -3.5}, {0, 0}}
は、[...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
と同じ意味になります。 ここでPoint
は構造体型です。配列の要素型が*Point
であるため、内側の複合リテラルPoint{...}
の前に&
とPoint
が自動的に補完されます。 -
構造体リテラルのフィールド値における型の省略: 構造体リテラル内で、フィールドの値が複合リテラルである場合、その型を省略できるようになりました。ただし、この省略はフィールド名がキーとして指定されている場合のみ適用されます。
例:
type List struct { Val int Next *List } &List{Val: 1, Next: {Val: 2}}
上記の例では、
Next
フィールドの型が*List
です。Next: {Val: 2}
の部分で、{Val: 2}
はList
型の複合リテラルです。この場合、Next
フィールドの型がポインタ型であるため、Next: &List{Val: 2}
と同じ意味になります。&List
の部分が省略されています。
これらの変更により、特にネストが深く、ポインタを多用するデータ構造の初期化において、コードがより簡潔に記述できるようになります。
コアとなるコードの変更箇所
変更は doc/go_spec.html
ファイルに対して行われています。
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -2118,11 +2118,26 @@ tmp[0 : n]\n Within a composite literal of array, slice, or map type <code>T</code>,\n elements that are themselves composite literals may elide the respective\n literal type if it is identical to the element type of <code>T</code>.\n+Similarly, elements that are addresses of composite literals may elide\n+the <code>&T</code> when the the element type is <code>*T</code>.\n+The same elisions may be applied to field values within a struct literal,\n+but only if the value has a field name key.\n </p>\n \n+\n+\n <pre>\n-[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}\n-[][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}\n+[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}\n+[][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5]}\n+\n+[...]*Point{{1.5, -3.5}, {0, 0}} // same as [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}\n+\n+type List struct {\n+\tVal int\n+\tNext *List\n+}\n+\n+&List{Val: 1, Next: {Val: 2}} // same as &List{Val: 1, Next: &List{Val: 2}}\n </pre>\n \n <p>\n```
## コアとなるコードの解説
この変更は、Go言語の仕様書に以下の新しいルールと例を追加しています。
1. **新しいルールの追加**:
```html
+Similarly, elements that are addresses of composite literals may elide
+the <code>&T</code> when the the element type is <code>*T</code>.
+The same elisions may be applied to field values within a struct literal,
+but only if the value has a field name key.
```
この部分が、ポインタ型要素の複合リテラルにおける `&T` の省略と、構造体リテラルのフィールド値における型の省略(フィールド名がキーの場合のみ)という新しい短縮記法を定義しています。
2. **新しい例の追加**:
```html
+[...]*Point{{1.5, -3.5}, {0, 0}} // same as [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}\n+\n+type List struct {\n+\tVal int\n+\tNext *List\n+}\n+\n+&List{Val: 1, Next: {Val: 2}} // same as &List{Val: 1, Next: &List{Val: 2}}\n```
これらの例は、上記で説明した新しい短縮記法がどのように適用されるかを示しています。
- 最初の例 `[...]*Point{{1.5, -3.5}, {0, 0}}` は、配列の要素が `*Point` 型であるため、内側の `Point` 複合リテラルが自動的に `&Point` に展開されることを示しています。
- 2番目の例は、`List` 構造体の `Next` フィールドが `*List` 型である場合に、`Next: {Val: 2}` が `Next: &List{Val: 2}` に展開されることを示しています。これは、フィールド名 `Next` がキーとして使用されているため、この短縮記法が適用されることを強調しています。
これらの変更は、Go言語の構文をより柔軟にし、特に複雑なデータ構造の初期化において、開発者がより簡潔で読みやすいコードを書けるようにするためのものです。
## 関連リンク
- Go言語の公式ウェブサイト: [https://golang.org/](https://golang.org/)
- Go 1リリースに関する情報: Go言語の公式ブログやリリースノートで詳細が確認できます。
## 参考にした情報源リンク
- Go言語仕様書 (Go 1): [https://golang.org/ref/spec](https://golang.org/ref/spec) (このコミットが変更を加えたドキュメントの最終版)
- Go 1リリースノート: [https://golang.org/doc/go1](https://golang.org/doc/go1)
- Go言語の複合リテラルに関するドキュメントやチュートリアル。
# [インデックス 10598] ファイルの概要
このコミットは、Go言語の仕様書 (`doc/go_spec.html`) に対する変更であり、複合リテラル (composite literal) の短縮記法に関する記述を更新しています。具体的には、Go 1 リリース計画の一環として、複合リテラル内で型を省略できる新たなケースが追加されました。これにより、コードの記述がより簡潔になります。
## コミット
commit 5f49456465f53f96bee03ac8cbe0d564e31576c2 Author: Russ Cox rsc@golang.org Date: Fri Dec 2 14:12:53 2011 -0500
spec: additional composite literal shortenings per Go 1 plan
R=golang-dev, gri, r, r
CC=golang-dev
https://golang.org/cl/5449067
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/5f49456465f53f96bee03ac8cbe0d564e31576c2](https://github.com/golang.com/go/commit/5f49456465f53f96bee03ac8cbe0d564e31576c2)
## 元コミット内容
spec: additional composite literal shortenings per Go 1 plan
R=golang-dev, gri, r, r CC=golang-dev https://golang.org/cl/5449067
## 変更の背景
この変更は、Go言語のバージョン1 (Go 1) のリリース計画の一部として行われました。Go 1は、Go言語の安定版としての最初のメジャーリリースであり、言語仕様の安定化と互換性の保証を目的としていました。このコミットは、その安定化プロセスの中で、複合リテラルの記述をより簡潔にするための改善提案が採用された結果です。
Go言語では、配列、スライス、マップ、構造体などの複合型を初期化する際に「複合リテラル」を使用します。初期のGo言語では、ネストされた複合リテラルにおいて、内部の型を明示的に記述する必要がありました。これは冗長であり、コードの可読性を損なう可能性がありました。Go 1の目標の一つは、言語をより使いやすく、効率的にすることであったため、このような冗長性を排除する方向で仕様が検討されました。
特に、ポインタ型を要素とする複合リテラルの初期化において、各要素の型を明示的に記述する必要があることは、コードの記述量を増やし、視覚的なノイズとなっていました。例えば、`[]*Date` 型のスライスを初期化する際に、`&Date{"Feb", 14}` のように `&Date` を毎回記述する必要がありました。このコミットで導入された短縮記法は、このような場合に `{"Feb", 14}` のように型を省略できるようにすることで、開発者がより自然にコードを記述できるようにすることを意図しています。これにより、コードの記述量が減り、視覚的なノイズが少なくなることで、コードの意図がより明確に伝わるようになります。
なお、Go 1では、複合リテラルにおける型の省略が導入されましたが、構造体リテラルにおいて、初期化される変数の型が既に分かっている場合に `v1 = {1,2}` のように型名を完全に省略するような、さらなる短縮記法はGo 1.xでは見送られました。これは、様々な影響が考慮された結果であり、Go 2での検討事項とされていました。
## 前提知識の解説
### 複合リテラル (Composite Literals)
Go言語における複合リテラルは、配列、スライス、マップ、構造体といった複合型の値を直接構築するための構文です。これらは、型名とそれに続く波括弧 `{}` で囲まれた要素のリストで構成されます。
例:
- 配列リテラル: `[3]int{1, 2, 3}`
- スライスリテラル: `[]int{1, 2, 3}`
- マップリテラル: `map[string]int{"a": 1, "b": 2}`
- 構造体リテラル: `struct { X, Y int }{X: 10, Y: 20}`
### 型の省略 (Elision)
Go言語では、コンテキストから型が推論できる場合に、型の記述を省略できる「型の省略 (type elision)」という機能があります。例えば、変数の宣言時に初期値がある場合、型を明示的に書かなくてもコンパイラが型を推論します (`var x = 10` は `var x int = 10` と同じ)。
複合リテラルにおいても、ネストされた複合リテラルの要素の型が、親の複合リテラルの要素型と同一である場合、その型を省略できるというルールが既に存在していました。
例:
`[][]int{{1, 2}, {3, 4}}` は、`[][]int{[]int{1, 2}, []int{3, 4}}` と同じ意味です。内側のスライスリテラル `[]int` の型が、外側のスライス `[][]int` の要素型 `[]int` と同じであるため、省略可能です。
### Go 1計画
Go 1は、2012年3月にリリースされたGo言語の最初のメジャーバージョンです。Go 1の主な目的は、言語仕様、標準ライブラリ、およびツールチェインを安定させ、将来のバージョンとの後方互換性を保証することでした。これにより、Go言語で書かれたプログラムが、将来のGoバージョンでも変更なしに動作することが期待されました。この安定化プロセスの中で、言語の使いやすさや表現力を向上させるための細かな調整も行われました。複合リテラルの短縮記法の追加も、その一環です。
Go 1で導入された複合リテラルの短縮記法は、特にポインタ型を要素とする複合リテラルにおいて、型を省略できるようにするものでした。これにより、コードの記述がより簡潔になり、`gofmt -s` コマンドによって既存のコードにも自動的に適用できるようになりました。
## 技術的詳細
このコミットは、Go言語仕様書 (`doc/go_spec.html`) の「Composite literals」セクションに、複合リテラルにおける型の省略に関する新たなルールを追加しています。
既存のルールでは、配列、スライス、マップ型の複合リテラル内で、要素がそれ自体複合リテラルであり、その型が親の要素型と同一である場合に型を省略できるとされていました。
このコミットによって、以下の2つの新しい短縮記法が追加されました。
1. **ポインタ型要素の複合リテラルにおける `&T` の省略**:
要素の型がポインタ型 (`*T`) である場合、その要素が複合リテラルのアドレス (`&T{...}`) であるならば、`&T` の部分を省略できるようになりました。つまり、`&T{...}` の代わりに `{...}` と記述できます。コンパイラは、要素の型がポインタ型であることから、自動的にアドレス演算子 `&` と基底型 `T` を補完します。
例:
`[...]*Point{{1.5, -3.5}, {0, 0}}` は、
`[...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}` と同じ意味になります。
ここで `Point` は構造体型です。配列の要素型が `*Point` であるため、内側の複合リテラル `Point{...}` の前に `&` と `Point` が自動的に補完されます。
2. **構造体リテラルのフィールド値における型の省略**:
構造体リテラル内で、フィールドの値が複合リテラルである場合、その型を省略できるようになりました。ただし、この省略は**フィールド名がキーとして指定されている場合のみ**適用されます。
例:
```go
type List struct {
Val int
Next *List
}
&List{Val: 1, Next: {Val: 2}}
```
上記の例では、`Next` フィールドの型が `*List` です。`Next: {Val: 2}` の部分で、`{Val: 2}` は `List` 型の複合リテラルです。この場合、`Next` フィールドの型がポインタ型であるため、`Next: &List{Val: 2}` と同じ意味になります。`&List` の部分が省略されています。
これらの変更により、特にネストが深く、ポインタを多用するデータ構造の初期化において、コードがより簡潔に記述できるようになります。
## コアとなるコードの変更箇所
変更は `doc/go_spec.html` ファイルに対して行われています。
```diff
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -2118,11 +2118,26 @@ tmp[0 : n]\n Within a composite literal of array, slice, or map type <code>T</code>,\n elements that are themselves composite literals may elide the respective\n literal type if it is identical to the element type of <code>T</code>.\n+Similarly, elements that are addresses of composite literals may elide\n+the <code>&T</code> when the the element type is <code>*T</code>.\n+The same elisions may be applied to field values within a struct literal,\n+but only if the value has a field name key.\n </p>\n \n+\n+\n <pre>\n-[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}\n-[][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}\n+[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}\n+[][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5]}\n+\n+[...]*Point{{1.5, -3.5}, {0, 0}} // same as [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}\n+\n+type List struct {\n+\tVal int\n+\tNext *List\n+}\n+\n+&List{Val: 1, Next: {Val: 2}} // same as &List{Val: 1, Next: &List{Val: 2}}\n </pre>\n \n <p>\n```
## コアとなるコードの解説
この変更は、Go言語の仕様書に以下の新しいルールと例を追加しています。
1. **新しいルールの追加**:
```html
+Similarly, elements that are addresses of composite literals may elide
+the <code>&T</code> when the the element type is <code>*T</code>.
+The same elisions may be applied to field values within a struct literal,
+but only if the value has a field name key.
```
この部分が、ポインタ型要素の複合リテラルにおける `&T` の省略と、構造体リテラルのフィールド値における型の省略(フィールド名がキーの場合のみ)という新しい短縮記法を定義しています。
2. **新しい例の追加**:
```html
+[...]*Point{{1.5, -3.5}, {0, 0}} // same as [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}\n+\n+type List struct {\n+\tVal int\n+\tNext *List\n+}\n+\n+&List{Val: 1, Next: {Val: 2}} // same as &List{Val: 1, Next: &List{Val: 2}}\n```
これらの例は、上記で説明した新しい短縮記法がどのように適用されるかを示しています。
- 最初の例 `[...]*Point{{1.5, -3.5}, {0, 0}}` は、配列の要素が `*Point` 型であるため、内側の `Point` 複合リテラルが自動的に `&Point` に展開されることを示しています。
- 2番目の例は、`List` 構造体の `Next` フィールドが `*List` 型である場合に、`Next: {Val: 2}` が `Next: &List{Val: 2}` に展開されることを示しています。これは、フィールド名 `Next` がキーとして使用されているため、この短縮記法が適用されることを強調しています。
これらの変更は、Go言語の構文をより柔軟にし、特に複雑なデータ構造の初期化において、開発者がより簡潔で読みやすいコードを書けるようにするためのものです。
## 関連リンク
- Go言語の公式ウェブサイト: [https://golang.org/](https://golang.org/)
- Go 1リリースに関する情報: Go言語の公式ブログやリリースノートで詳細が確認できます。
## 参考にした情報源リンク
- Go言語仕様書 (Go 1): [https://golang.org/ref/spec](https://golang.org/ref/spec) (このコミットが変更を加えたドキュメントの最終版)
- Go 1リリースノート: [https://golang.org/doc/go1](https://golang.org/doc/go1)
- Go.dev: Composite literals in Go 1 (Web検索結果より)
- Golangbridge.org: Go 1.x and Go 2 discussions on composite literal shortenings (Web検索結果より)