やっつけな日常(24) Rustに入ればRustに従え、メモリの管理、独特、でも安全かも。

Joseph Halfmoon

前回は、ラズパイ4にRust言語インストールしてお試しを始めました。今回はWSL1上のUbuntuでRust言語の「核心」メモリ管理をちと触ってみたいと思います。「クセが強い」感じがしてます。けれどもそのクセの背後には安全な操作を担保するための慮りが入っている、らしいです。受け売り。まあトレーニングあるのみ。

※今回の動作確認には WSL1(Ubuntu 20.04.4 LTS)上の rustc 1.62.0 を使用しています。WindowsPC上で走っているVSCodeからWSLにリモート接続して作業しています。なお、VSCode上のRUST言語用のプラグインとして以下を使用させていただいとります。なかなかいい感じでないかい。

rust-analyzer v0.3.1123

ミュータブルにイミュータブル

コンテンポラリな言語の通例にもれず(なんだそれ?)Rustの変数も基本はイミュータブル、書き換え不能であるようです。しかし、イミュータブルばかりで書くのは大変なので、mut というキーワードがあります。これをつけるとミュータブルな変数になるというもの。最初、Rust言語のソースを見た時に、これは何?とおもった一物。以下はイミュータブルな配列に代入しようとして拒否られているコードです。

ERROR01

VSCodeに上記のプラグインを導入すると

    • ミュータブルな変数には下線を引いてくれる。
    • ミュータブルな変数に代入しようなどと不埒なことをすると赤波線でエラー

となります。便利。

なお、イミュータブルな変数を let を使って上書き定義することができるようです。たとえば内側のスコープで別な値に上書き定義して使用し、スコープ抜けたら元に戻っている、みたいな使い方ができるようです。知らんけど。

ヒープにおかれたオブジェクトに所有権

Rust言語にも動的なメモリオブジェクトを保存するためのヒープはあるのですが、1つクセが強いところがありそうな。まずはクセが強くない性質から。

変数のスコープは{ }で管理できる

{ }内で宣言した変数は { } を抜けると回収されて存在しなくなるようです。そして、「所有権」という概念をのぞけば、次に分かり易いのは以下の仕組みかと。

ヒープの所有権を持つ変数が回収されるとヒープも開放される

CやC++のように明示的に関数を呼び出してヒープを解放するのでもなく、Go言語のようにギャベージ・コレクタが使わなくなったメモリを回収して回るのでもなく、スコープを抜けたときに回収されると。分かり易いんでないかい。

しかし、ヒープに置いてあるオブジェクトって、どこか1か所から参照するわけでなくて、異なるスコープの複数のポイントで参照されるよね。多重開放とか問題じゃん。それに対するRust様のお答えが所有権らしいです。以下にありがたい日本語ドキュメントへのリンクを貼り付けておきます。

所有権とは?

ヒープ上のオブジェクトには所有権というものが設定され、アクセスできる変数にそれが与えられると。しかし、別な変数にヒープ上のオブジェクトにアクセスできるポインタが渡ってしまうと、所有権もまた移転するようです。所有権を失った変数からはもはやアクセスできんです。

下は文字列リテラル(所有権気にしなくてよい)と、ヒープ上にとられたString型のオブジェクト(当然所有権あり)で、変数コピーをした例です。

ERROR02Code

上記のs1の下に赤の波線あり、エラーとなっています。エラーメッセージが以下に。move つまり所有権の移転が起こっているので s1 はもはや使えんぞ、と御叱り。ERROR02
勿論、データオブジェクトそのものを「ディープコピー」してしまえば実体の異なるメモリオブジェクトとなるのでそれぞれ別個の所有権となり共存共栄?

つまり、所有権を持っている変数がスコープから外れたときだけ、ヒープは回収され、失っている変数が外れても何もせんでええ、という割り切り。分かっていて使う分には、安心、安全、分かり易い?

今回実験につかったコードの全体と実行結果

エラーになるところはコメントアウトした、実行可能なRustのコードが以下に。

SRC

プラグインのお陰で、main関数の上にある Runボタンを押せば、そのままTerminalウインドウでソースがビルドされ、実行されます。こんな感じ。

Result

ようやくRustの最初の一歩か。

やっつけな日常(23) ラズパイ4に Rust言語処理系をインストール。野望?は広がる へ戻る

やっつけな日常(25) Goに入ればGoに従え、そんなことできるの?ヒープ・エスケープ へ進む