メインコンテンツにスキップ
モジュール 3 · レッスン 1 / 2コース内の 5/14~15 min
モジュールのレッスン (1/2)

所有権のルール

所有権は Rust の最もユニークな機能です。これにより、ガベージ コレクターを使用したり、(C や C++ のように) 手動でヒープ メモリの割り当てを解除したりすることなく、言語でメモリの安全性を保証できます。

所有の3つのルール

Rust のメモリ管理は、コンパイラによって厳密にチェックされる 3 つの単純なルールによって管理されます。

  1. Rust の各値には、その所有者と呼ばれる変数があります。
  2. 一度に存在できる所有者は 1 人だけです。
  3. 所有者がスコープ外になると、値は自動的に削除されます。

スタックとヒープ

所有権を理解するには、データがどこに存在するかを知ることが重要です。

  • スタック: コンパイル時に既知の固定サイズのデータ​​ (整数、ブール値など) を格納します。アクセスは非常に高速です。
  • ヒープ: コンパイル時に不明な動的サイズのデータ​​を保存します (例: String)。割り当ては遅くなり、スタックにポインタを保存する必要があります。

「動く」という概念

ヒープに割り当てられた変数を別の変数に割り当てると、Rust は値の所有権を 移動 (または転送) し、最初の変数を無効にします。

Rust
let s1 = String::from("ciao");
let s2 = s1; // Ownership of the text moves to s2. s1 is NO longer usable!

// println!("{}", s1); // COMPILATION ERROR! s1 is "borrow of moved value"
println!("{}", s2); // Valid!

この動作により、s2 のみがメモリを解放するため、「二重解放エラー」(スコープ外に出るときに同じメモリを 2 回解放しようとする) が回避されます。

「クローン(ディープコピー)」の概念

String の内容全体 (スタック ポインターとヒープ内の実際のテキスト データの両方) を明示的にコピーする必要がある場合は、.clone() メソッドを使用できます。これにより、ヒープ上のデータが完全に複製され、元の変数と新しい変数の両方が有効なままになりますが、新しいメモリ割り当てによるパフォーマンスのオーバーヘッドが発生します。

Rust
let s1 = String::from("ciao");
let s2 = s1.clone(); // Deep copy. Both variables remain valid!
println!("s1: {}, s2: {}", s1, s2);

「コピー」という概念

スタックに完全に保存されている単純型 (整数 i32、ブール値 bool、文字 char など) の場合、代入によって実際の 自動シャロー コピーが実行され、両方の変数が有効なままになります。

Rust
let x = 5;
let y = x; // Copies the value 5 onto the stack. Both variables are usable!
println!("x: {}, y: {}", x, y); // Valid!

自分で試してみてください

運動#rust.m3.l1.e1
試行回数: 0読み込み中…

テキスト「hello」を含む文字列 s1 を宣言します。 s1 を s2 に割り当てます (所有権を移動するため)。最後に、println! を使用して s2 を出力します。

エディターを読み込み中…
ヒントを表示

`let s2 = s1;` を使用して所有権を `s2` に移し、それを `println!('{}', s2);` で出力します。

3 回の試行後に解決策が利用可能になります

運動#rust.m3.l1.e2
試行回数: 0読み込み中…

値 5 の整変数 x を宣言します。x を y に代入します (コピーを実行します)。最後に、x と y の両方を同じ println で出力します。声明。

エディターを読み込み中…
ヒントを表示

`let y = x;` を実行し、両方の値を出力します (例: `println!('{} {}', x, y);`。

3 回の試行後に解決策が利用可能になります

運動#rust.m3.l1.e3
試行回数: 0読み込み中…

Declare a String s1 with the value "Rust". Create a deep copy of s1 in a new variable s2 using the clone method. Finally, print both s1 and s2 separated by a space using the println! macro.

エディターを読み込み中…
ヒントを表示

Use `let s2 = s1.clone();` to deep copy the value of `s1` into `s2`, then print them with `println!("{} {}", s1, s2);`.

3 回の試行後に解決策が利用可能になります