【Rustの所有権システムまとめ 〜その1〜】値と変数の区別

最近Rustに入門しています. Rustは所有権システムによってメモリ安全性を保証しつつもCやC++と同程度の性能を持つシステムプログラミング言語として最近注目されてきています.

その中で,Rustの一番の特徴である所有権システムについて自分なりにまとめてみようと思いこの記事を書いています.

書こうと思ったら長くなりそうだったので連載という形にしていきます. 今回は,所有権システムの前に前提となる値と変数の区別について書いていきます.

プログラムにおけるデータ

まずは,重要だけど一般にはあまり注意が払われていないデータについて説明していきます.

プログラマが書いたコードには,様々なデータ構造が存在することがほとんどのはずです. 例えば下のコードは,100という値を64bit符号なし整数型(u64)の変数xに可変束縛しています.

let mut x: u64 = 100;

束縛とか難しい用語使ってるけど要は「変数xに100という値を代入」しているんでしょ,と普通は理解すると思います. しかし,ここをもっとちゃんと理解することは個人的には大事だと思っています. というのも,この記事の本編で扱う所有権システムを初め,Rustではデータに関連する概念が多く出てきてあやふやなまま理解しようとしても混乱するからです.

プログラムを実行している時,データはメモリのどこかに置かれます(実際に計算を行うときにはCPUのレジスタに移されますがここでは割愛します).どこかといっているのは,関数の引数などスタック領域にある場合もあればヒープ領域に動的にメモリが確保されることもあるからですが,いずれにせよメモリ中にあることには変わりがないです.このようにメモリに置かれたデータそのもののことは一般に「値(value)」と呼ばれます.

変数

しかし,実際にプログラミングをする際には生の値だけを使っているわけではなく,値を「変数(variable)」に代入して使うことが多いと思います.実際,上のコードでは100という値をxという変数に入れています.このように「値を変数に代入する」,という理解でも間違ってはいないのですが,Rustではもっと的を得た「値を変数に束縛する(bind value to variable)」といった表現が使われます.

この表現では値と変数を明確に別のものと捉えており,ある値をある変数に結びつけることを束縛と表現しています.イメージとしては,あるメモリ領域(及びそこに存在する値)に対して変数が鎖を付けるといった感じでしょうか. また,値が実際にメモリ中に存在しているデータであるのに対し,変数はただ単にあるメモリ領域に名前をつけただけである,ということも重要な理解です.

以上の説明は,下のような図にまとめられます.

値と変数の関係

この図は,例えばこのようなコードがあった時のものです.

let x: usize = 100;
let y: isize = -50;

変数xとyのそれぞれは,100と-50という値を束縛しています. ただし,100や-50といった値は実際にメモリに存在しているのに対し,xやyといった変数はあくまでもプログラム中の概念であり,実行中のメモリにxそのものが存在しているわけではありません*1*2

次回

次回は,いよいよ所有権システムについて説明していきます.

*1:デバッグシンボルなどを含めたバイナリには変数の情報はありますが,あくまでもそれはプログラムと実際の実行の架け橋として存在しているに過ぎません

*2:インタプリタ型言語などランタイムがあるような言語では変数そのものの情報が含まれていることも珍しくはないはずです