はじめに
アイマス19周年おめでとうございます!20周年イヤー楽しみ!
nikkieです。
TechRAMEN関連エントリです。
『プログラミングRust 第2版』の所有権まわり(4章・5章)をざっと読んだログです1。
目次
- はじめに
- 目次
- t_wadaさんによるLT「これまでと違う学び方をしたら挫折せずにRustを学べた話」
- 動作環境
- 読書メモ:所有権の移動
- 体感するサンプルプログラム
- 移動する代わりに借用もできる
- 終わりに
t_wadaさんによるLT「これまでと違う学び方をしたら挫折せずにRustを学べた話」
Rust はこれまで私が学んできた言語とはどう違うのか、どう学んだら突然理解できるようになったのか、自分の体験を話したいと思います。
どうやったらRustがわかるようになったのか?
— 0yu(おゆ) (@yud0uhu) 2024年7月27日
→プログラミングRustを読んだらわかるようになった(終)#techramen24conf #syoyu pic.twitter.com/XXJ0b2Pg1K
"プログラミングRust第2版を読む"
— YAMAKAWA, Hiroto (@gishi_yama) 2024年7月27日
終
制作・著作
━━━━━
t-wada#techramen24conf #shoyu
『プログラミングRust 第2版』を私も読んでいきます!
動作環境
% rustc --version rustc 1.80.0 (051478957 2024-07-21) % cargo --version cargo 1.80.0 (376290515 2024-07-16)
読書メモ:所有権の移動
Rustの所有権ってずっとよく分からない感覚だったので、t_wadaさんのLTで聞いた 4章「所有権と移動」を読みました2。
Rustはプログラム中でのポインタの使い方に制約を加えたのだ。(4章冒頭より)
4.1で所有という概念を導入。
- 値はヒープ上にある
- 所有者として、関数のスタックフレーム上のローカル変数
- ヒープ上のバッファ(値がある)を所有
- ここがポインタですね
Rustではすべての値はその生存期間を決定する唯一の所有者を持つ。(4.1)
そして4.2で値がある所有者から別の所有者へと移動するという考え方が説明されます。
値が別のポインタ(別の所有者のポインタ)から指されるようになるんだ!
Rustでは、ほとんどすべての型が、変数への値の代入、関数への引数の受け渡し、関数からの返り値の返却の際にコピーされず、移動(move)される。(4.2)
所有権の移動って、私は代入の挙動きっかけで知ったのですが、関数呼び出しにも登場してるんですね
体感するサンプルプログラム
4.2.3より
- 2行目の
Vec::new()
呼び出しで所有権が移動している!- 空のベクタ3の値は
v
が所有するように移動
- 空のベクタ3の値は
for
文では可変なv
を、101から105までの整数(i32
)からなるベクタとしている- このベクタを作る中でも、
i.to_string()
呼び出し、そして、返り値をベクタのpush
に渡す箇所は、どちらも所有権の移動 - 返した値(
String
)はベクタのインデックスが所有(図4-9 参照)
- このベクタを作る中でも、
ここでベクタの(先頭を1番目として)3番目の要素を取り出そうとします。
ここまでの延長で浮かぶlet third = v[2];
と書くと、コンパイルエラー。
これが書けると3番目の要素の移動(3番目の要素が未初期化となる)ため、書けないようにコンパイルエラーです。
移動する代わりに借用もできる
この解消については、5章の「参照」に分かれています。
強調するために、Rustはある値に対する参照を作ることを借用(borrowing)と呼ぶ。(5章冒頭)
移動の代わりに借用すると、コンパイルできます!(サンプルコード参照)
String型への参照(共有参照)ですね。
% cargo run [] ["101", "102", "103", "104", "105"] Third element is 103
5章を拾い読み4する中で、なるほどと思ったのが以下。
参照があまりに一般的に使われるので、Rustでは
.
演算子が、必要に応じて暗黙に左のオペランドを参照解決するようになっているのだ。(5.2.1)
println!
マクロもコードとしては.
演算子を使うとのこと。
私が認識していない範囲で、借用に助けられていたんですよ!
出力した後も同じ変数で値を扱えるのは、所有権が移動していなかったから、つまり参照の恩恵なんだ!
この記載からv.push()
は、可変参照を使った(&mut v).push()
と同じと理解しました
終わりに
t_wadaさんのLTきっかけに読みたくなった『プログラミングRust 第2版』の4章・5章のログでした。
所有権の移動と借用(参照)、この2つの概念の解説で、これまで私は所有権を掴み損なっていたんだなあと思い知りました。
移動は変数への代入だけでなく、関数呼び出しや返り値でも起こっていたんですね。
そしてprintln!
マクロでデバッグして、私がRustを分からないなりにも書けていたのは、このマクロのコードが暗黙に借用していたから!(出力したい値の所有権が移動していなかったんだね)
読んだことで、Rustプログラムでやっていることがだいぶ見えるようになりました。
過去に分からないなりに書いたプログラムの理解度もだいぶ上がった感覚です。
Ryeやuvなどもっと読めるようになりたいソースがあるので、引き続きRustに取り組んでいきます。
今回の所有権まわりの理解は、ハーケンな気がします