Rust 速習チュートリアル

Rust の所有権

1. 所有権 (Ownership)

Rustは、メモリを安全に管理するために「所有権(Ownership)」という仕組みを採用しています。
Rustにおけるすべての値には所有者(Owner)が存在し、通常はその所有者は変数となります。

2. 所有権の規則

所有権には、以下の厳格なルールがあります。

  • 各値には、たった一つの所有者が存在する
  • 所有者がスコープ(Scope)から外れると、その値は破棄(デリート)される
  • 一度につき所有者は一人だけであり、所有権を「借用(Borrowing)」しない限り、複数の所有者を持つことはできない(借用については次章で解説します)

3. 所有権の基本例

以下の例では、変数 a が文字列の所有権を持っています。その後、その所有権を b に移動(Move)させます。

サンプルコード

let a = String::from("Hello");
let b = a;

// println!("{}", a); // エラー: aはもはや値を所有していません
println!("{}", b); // OK: 現在はbが値の所有者です

ab に代入した時点で、所有権が移動(Move)します。これは、a が無効になり、b だけがその値を使用できるようになったことを意味します。

3.1 プリミティブ型のコピー

ただし、数値、文字(char)、ブーリアン(bool)などの単純なデータ型は、移動ではなくコピー(Copy)されます。
そのため、別の変数に代入した後でも、元の変数を使用し続けることができます。

サンプルコード

let a = 5;
let b = a;
println!("aの値 = {}", a); // 動作します
println!("bの値 = {}", b); // 動作します

この例では、a の値が b にコピー(Copy)されており、移動(Move)ではないため、代入後も両方の変数を利用可能です。

4. クローン (Clone)

String のような型で、元の値を保持したまま別の変数にも同じ値を代入したい場合は、データそのものを複製する .clone() メソッドを使用します。

サンプルコード

let a = String::from("Hello");
let b = a.clone(); // これで両方の変数が同じ値を持つようになります

println!("aの値 = {}", a); // 動作します
println!("bの値 = {}", b); // 動作します

ただし、同じ値を2つ所有する必要がない場合は、クローンを作成するよりも「参照(&)」を使用する方が効率的です。これについては次章で詳しく学びます。

5. 所有権が重要である理由

所有権を理解することは、エンジニアにとって以下の大きなメリットがあります。

  • 自動的なメモリ解放: メモリが不要になったタイミングで、Rustが自動的に解放してくれます。
  • メモリバグの防止: すでに削除されたメモリにアクセスしようとするようなバグを防ぎます。
  • パフォーマンスの向上: これらはRustが「安全かつ高速」である理由の核心部分です。