Rustの所有権の理解について適当に書きたい
どうやらRustの所有権の難しさというか、ハードルの高さがまた話題になってるっぽいので、前から温めておいた話題でひとつ記事を書きたいなと
自分はなにかについて学習する時、全体像を抽象化、把握しないと思考がまとまらないタイプの人間なのですが、そういう意味でRustはかなり難しい言語であると感じています
Rustは本来低レイヤープログラミング言語であり、アプリケーション層での使用を目標にしている訳では無いため、普段使う言語とは体系に違いが多いです
この記事で自分の理解認識について共有し、あわよくば記事を見た有識者に認識のズレや他の考え方について教えてもらいたいと思って記事を書きます
普段使う言語がTypeScriptなので、TSと比較するような内容が多いですが、GC付きの言語なら大抵当てはまる話なのではないかと思います
本題
自分の理解では、Rustの所有権は現実の物体のことと紐づけて考えることができると思っています
まずは前提から話します
一般的にTSのようなGC付き言語では、変数のスコープについてのみ考えれば何とかなることが多いです
スコープが狭いところからグローバル変数に代入することで変数をプログラム全体に共有することすらもできます
let manager;
function init() {
const _manager = create_manager(config);
manager = _manager;
}
これは、TypeScriptのランタイムが全ての変数を管理し、コード中の変数とメモリ上の変数の中身を紐づける作業を行っているからですが、Rustではコードをコンパイルした結果である実行バイナリ自身が変数を管理する必要があります
バイナリの中に変数管理機構を埋め込み、TSと同等の動作を行うことは可能ですが、Rustはより最適化された動作のために異なる道を選びました
それが所有権です
Rustの所有権は細かい仕様が多いので詳解は公式ドキュメントなどに譲りますが、自分はこの動作を現実の物体のように考えるべきだなと思いました
例えば関数initで変数configを初期化したとします
この時、configという物体(以降データと呼びます)はinitさんが所有していると考えるわけです(所有権と言うネーミングは本当にきっちりハマっていると思います)
fn init() {
let manager = create_manager(config);
}
このコードを実行した時は、initさんが持っていたデータを全権限ごとcreate_managerさんにぶん投げたとすることが出来ます
そして、create_managerの全処理が終わった時、create_managerさんは役割を果たしたとして、自分にとってもう必要なくなったconfigごと消滅します (!?)
参照のことを考えると、&configはconfigを見る権利のことを指し、それをcreate_managerさんに与えているだけなので、create_managerさんが消滅してもデータ自体はinitさんが所有しているままと言うわけです
(可変参照も同じようなものですが、都合が悪いため同時に1人までのみ権利を与えることが出来ます)
ライフタイムの概念をこの例えに導入すると、データは作成した時点でライフタイム(消費期限のある)のあるなまものであり、完了するまでに消費期限の切れる可能性がある処理にはデータを渡せないと考えられると思っています
もちろん細かいエッジケースについて書けばいくらでも例えることが出来ますが、大枠ではこんな感じじゃないでしょうか
ちなみに所有権を実際の物体に例えること自体は、公式のドキュメントにありますが1部1部にポイント的に掲載されているだけであり、例えを前面に押し出している感じでは無いです(わかりやすいからもっと自信もって推して欲しい、丸々一章使って概念を解説してくれ)
TSなどの言語とRustで考え方が違う根本には、TSでは実質全ての変数が参照のようなものであるのに対し(メモリ管理上は)、Rustではデータの実体と参照と1次元データの扱いの差があると思います
GC付き言語では、データの実体の扱いはGCが隠蔽し、参照のみに統一することで考えることを1次元減らし、簡単にしてくれているという訳です
あまりまとまった記事ではありませんが、ぜひ考え方について共有してもらえると嬉しいです
Discussion