値型、参照型、ポインタ型
「 Goのポインタ型のまとめ 」で、値型、参照型、ポインタ型の3つを並立関係であるかのように書きました。分かりやすさのためにそう書きましたが、これは自分の本意ではないので、ここにまとめます。
値型と参照型は並立関係にありますが、ポインタ型はこれらと並立関係にあるとは考えていません。ポインタ型はint型やchar型と並立されるべきものです。つまり、ポインタ型変数は、(int型やchar型と同じ意味で)ポインタ型の値を持つ値型変数です。
値型変数は、変数がそのまま値のサイズのメモリ領域を占め、代入で値のサイズのメモリのコピーが起きます。
この用語定義を使うと、C言語の変数はすべてが値型です。例外はありません。配列型も値型です。配列型の場合、代入できない、ポインタ型変数へ代入すると暗黙にアドレス参照演算が起きる、というささやかな暗黒面はありますが、そこを除けば、全体に一貫性はあります。
Rubyの変数は(概念上)すべて参照型です。「概念上」という但し書きが気になる人は、「 Ruby勉強会資料 」を見てください。Rubyの代入は、オブジェクトのアドレス値のコピーをしていると見なしても、全体の整合性は崩れません。Rubyもまた全体の一貫性があります。
Lispも(概念上)すべて参照型です。概念的には、Lispのシンボルは、「値(ポインタ値も含む)のハッシュテーブルのキー」と考えることができます。概念的と言いながら、ハッシュテーブルという実装上の用語を使う必然性はありませんが、イメージしやすさのために使いました。これを見て分かるように、参照型変数の値はアドレス値である必然性はありません。書籍「 パーフェクトJava 」の中でもくどく繰り返していますが、そもそも参照型変数というのは、その値を意識すべきものではありません。これは値型変数と異なる部分です。
ここまで一貫性のある言語の例でした。
Javaは、基本型変数は値型で、それ以外すべて参照型です。この非一貫性でJavaを批判する人がいますが、ぼくはJavaの決定を悪い決定だとは思っていません。「 JavaよりCが好き 」と書きましたが、Javaを嫌いとは言っていません。現時点では最も妥当な決定だと思います。
で、Goです。基本的に値型です(ポインタ型も含めて)が、mapとsliceとchannelだけ参照型です。概念的には納得感に欠ける決定です。たぶん、使えばすぐに慣れると思いますが。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/types/tbping