所有権の3つのルール
Rustの所有権は、ヒープ上の値を安全に管理するための仕組みです。基本は次の3つです。
- Rustの値には所有者が一人いる
- 所有者が別の変数へ移ると、元の変数は使えない
- 所有者がスコープを抜けると値は自動的に片付けられる
ガベージコレクターに任せるのではなく、コンパイル時に所有者と利用期間を確認する点がRustの特徴です。
Stringを代入するとmoveする
Stringはヒープ上のデータを持つため、単純な代入ではデータを二重に解放しないよう所有権が移動します。
所有権の移動RUST
fn main() {
let first = String::from("Rust");
let second = first;
println!("{second}");
}実行結果OUTPUT
Rustこの後にprintln!("{first}")を書くと、borrow of moved valueというコンパイルエラーになります。firstはもう値の所有者ではありません。
Copyとcloneの違い
整数やboolなどの単純な型はCopyなので、代入後も元の変数を使えます。Stringなどを複製したいときは明示的にcloneします。
CopyとcloneRUST
fn main() {
let number = 10;
let copied = number;
println!("{number} {copied}");
let original = String::from("Rust");
let cloned = original.clone();
println!("{original} {cloned}");
}実行結果OUTPUT
10 10
Rust Rustcloneの使いすぎに注意cloneはデータを複製する処理です。所有権を移動すべきか、参照を借用すべきかを考えてから使います。
関数へ渡すと所有権も移る
関数へStringを渡すRUST
fn print_name(name: String) {
println!("{name}");
}
fn main() {
let name = String::from("Mity");
print_name(name);
}この場合、関数がnameの所有者になります。呼び出し元でも使い続けたい場合は、次の借用と参照で学ぶ&strや&Stringを使います。
練習
Stringを受け取る関数と、&strを受け取る関数をそれぞれ作り、呼び出し後に元の文字列を使えるか比べてみましょう。