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

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

コミット

コミットハッシュ: 8a8445ba71b18f9a4dcdd7e50a6e821afcbfe2ed 作者: Russ Cox rsc@golang.org 日付: Fri Dec 2 13:11:30 2011 -0500

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

https://github.com/golang/go/commit/8a8445ba71b18f9a4dcdd7e50a6e821afcbfe2ed

元コミット内容

spec: pointer to array can be sliced

This has always been true, but we lost it from the spec
somewhere along the way, probably when we disallowed
the general 'pointer to anything sliceable' slice case.

R=gri
CC=golang-dev
https://golang.org/cl/5437121

変更の背景

このコミットは、Go言語の仕様書(doc/go_spec.html)において、配列へのポインタがスライス可能であるという事実が明示されていなかった点を修正するものです。コミットメッセージによると、この機能自体はGo言語の設計当初から常に真実であり、実装上もサポートされていました。しかし、過去の仕様変更、特に「任意のポインタがスライス可能である」という一般的なケースが禁止された際に、配列へのポインタがスライス可能であるという特定のケースが誤って仕様書から抜け落ちてしまったと考えられます。

この変更の背景には、言語仕様の正確性と完全性を保つというGo言語開発チームの強いコミットメントがあります。言語仕様は、プログラマがGoコードの挙動を理解し、コンパイラやツールが言語を正しく実装するための唯一の信頼できる情報源です。そのため、実装と仕様の間に不一致がある場合、それはバグと見なされ、修正されるべきです。このコミットは、既存の言語の挙動を仕様に正確に反映させるための「仕様の同期」作業の一環と言えます。

前提知識の解説

Go言語における配列とポインタ

  • 配列 (Arrays): Go言語の配列は、同じ型の要素を固定長で連続して格納するデータ構造です。宣言時にサイズが決定され、そのサイズは型の不可欠な一部となります(例: [5]int[10]int は異なる型です)。
  • ポインタ (Pointers): ポインタは、変数のメモリアドレスを保持する変数です。Goでは、&演算子で変数のアドレスを取得し、*演算子でポインタが指す値にアクセス(デリファレンス)します。例えば、var x int; p := &x とすると、pxのメモリアドレスを指すポインタになります。

Go言語におけるスライス (Slices)

スライスはGo言語の強力な機能の一つで、配列の上に構築された動的なビューを提供します。スライスは、基になる配列の一部を参照し、長さと容量を持ちます。

  • スライスの作成: a[low:high] の形式で作成されます。これは、alowインデックスからhigh-1インデックスまでの要素を含む新しいスライスを生成します。
  • スライス可能な型: 通常、Goでは文字列、配列、または既存のスライスがスライス可能です。このコミット以前の仕様では、配列へのポインタが明示的にスライス可能であるとは記載されていませんでした。

言語仕様 (Language Specification)

プログラミング言語の仕様書は、その言語の構文、セマンティクス、および標準ライブラリの挙動を正式に記述した文書です。Go言語の仕様書は、Goプログラムがどのように解釈され、実行されるべきかを定義しており、コンパイラの実装者や言語のユーザーにとって非常に重要です。仕様書は、言語の「真実の源」として機能し、異なるコンパイラやプラットフォーム間での一貫した挙動を保証します。

技術的詳細

Go言語において、配列へのポインタをスライスできるという挙動は、ポインタのデリファレンスとスライス操作の組み合わせによって実現されます。

例えば、var arr [10]int という配列があったとします。この配列へのポインタは p := &arr となります。 Go言語では、ポインタが指す配列に対して直接スライス操作を行うことができます。これは、p[low:high] のように記述できます。この操作は、内部的にはまずポインタpをデリファレンスして基になる配列arrにアクセスし、その配列に対してスライス操作 arr[low:high] を適用するのと同等です。

この挙動は、特にC言語のポインタ演算に慣れているプログラマにとっては直感的かもしれません。C言語では、配列名がその配列の先頭要素へのポインタとして扱われるため、ポインタ演算と配列アクセスが密接に関連しています。Go言語では、ポインタと配列は明確に区別されますが、このスライス機能は、配列へのポインタを介して配列のサブセクションにアクセスする柔軟な方法を提供します。

この仕様の明記は、Go言語の型システムと操作の一貫性を保つ上で重要です。もし仕様に記載がなければ、この挙動が将来的に変更される可能性や、異なるコンパイラ実装間で挙動が異なる可能性が生じます。今回の修正により、配列へのポインタのスライスが言語の正式な一部として保証され、プログラマは安心してこの機能を利用できるようになります。

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

変更は doc/go_spec.html ファイルの1箇所のみです。

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -2440,7 +2440,7 @@ Assigning to an element of a <code>nil</code> map causes a
 <h3 id="Slices">Slices</h3>
 
 <p>
-For a string, array, or slice <code>a</code>, the primary expression
+For a string, array, pointer to array, or slice <code>a</code>, the primary expression
 </p>
 
 <pre>

コアとなるコードの解説

この変更は、Go言語の公式仕様書である doc/go_spec.html の「Slices」セクションにある記述を修正しています。

元の記述: For a string, array, or slice <code>a</code>, the primary expression (文字列、配列、またはスライス a の場合、プライマリ式は)

変更後の記述: For a string, array, pointer to array, or slice <code>a</code>, the primary expression (文字列、配列、配列へのポインタ、またはスライス a の場合、プライマリ式は)

この修正により、スライス操作の対象となる型に「配列へのポインタ (pointer to array)」が明示的に追加されました。これは、Go言語のコンパイラが既にサポートしている挙動を、言語の公式仕様に正確に反映させるための変更です。これにより、Go言語の仕様書が実際の言語の挙動と完全に一致するようになり、仕様の信頼性と正確性が向上します。

関連リンク

参考にした情報源リンク