0Pricing
Learn Rust Coding · レッスン

Box、Rc、Arcスマートポインタ

ヒープ確保を行う`Box`、共有所有権を実現する`Rc`、スレッドセーフな共有所有権を実現する`Arc`によるデータ管理を理解します。

「Box、Rc、Arcスマートポインタ」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全3レッスンが含まれています。

スマートポインターとは

Rustの所有権システムはメモリ安全性に優れていますが、より柔軟な扱いが必要になる場合もあります。そこで活躍するのがスマートポインターです。

スマートポインターは、ポインターのように機能しながら、追加のメタデータや機能も備えたデータ構造です。メモリ、所有権、その他のリソースを自動的に管理します。

Box:ヒープにデータを格納する

最も単純なスマートポインターはBox<T>です。データをスタックではなくヒープに格納できます。

  • スタック:高速で、サイズが固定されたデータ。
  • ヒープ:低速ですが、実行時に割り当てられる柔軟なサイズのデータ。

値をBoxに入れると、Box自体はスタック上に置かれますが、指し示すデータはヒープ上に置かれます。

Boxを使ったヒープ割り当て

Boxによってデータがヒープに移される仕組みを見てみましょう。これは、大きなデータを扱う場合や、コンパイル時にサイズが分からない場合に便利です。

このコードを実行して、値がBox化される様子を確認してください。

fn main() {
  let x = 5; // x is on the stack
  let boxed_x = Box::new(x); // x's value is moved to the heap, boxed_x is on stack
  println!("Value on stack: {}", x);
  println!("Value in Box (on heap): {}", *boxed_x); // Dereference to get value
}

Boxが役立つ場面

次のような状況でBox<T>を使用できます。

  • コンパイル時にサイズが分からない型を、サイズが既知で固定された場所に格納する必要がある場合。
  • 大量のデータを扱い、データ自体をコピーせずに所有権を移動したい場合。
  • traitオブジェクト(例:Box<dyn Trait>)を所有したい場合。

Rc:複数の所有者(単一スレッド)

Rustの所有権ルールでは、通常、1つの値には1つの所有者しか存在できません。しかし、プログラムの複数の部分で同じデータを「所有」する必要がある場合はどうすればよいでしょうか。

Rc<T>(Reference Counted)を使うと、単一スレッドの状況で複数の所有者がデータを共有できます。データを指す参照の数を追跡します。

参照カウントが0になると、データは解放されます。

Rcでデータを共有する

Rc::clone()は参照カウントを増やします。これはディープコピーではなく、同じデータを指す別のポインターを作成するだけです。

データが共有され、異なる「所有者」からその値にアクセスできることに注目してください。

use std::rc::Rc;

fn main() {
  let value = Rc::new(String::from("Shared String"));
  println!("Count after creation: {}", Rc::strong_count(&value));

  let value_clone_a = Rc::clone(&value); // Increment count
  println!("Count after clone A: {}", Rc::strong_count(&value));

  {
    let value_clone_b = Rc::clone(&value); // Increment count
    println!("Count after clone B: {}", Rc::strong_count(&value));
    println!("Data from A: {}", value_clone_a);
    println!("Data from B: {}", value_clone_b);
  } // value_clone_b goes out of scope, count decreases

  println!("Count after B goes out of scope: {}", Rc::strong_count(&value));
}

Arc:共有所有権(マルチスレッド)

Rc<T>は単一スレッドのアプリケーションで適しています。しかし、複数のスレッド間でデータを共有する必要がある場合、Rc<T>は安全ではありません。

Arc<T>(Atomic Reference Counted)は、Rc<T>のスレッドセーフ版です。アトミック操作を使用して参照カウントを更新し、スレッド間での安全性を保証します。

Arcはアトミック操作を行うため、Rcと比べてわずかなパフォーマンス上のオーバーヘッドがあります。

Arcでスレッド間のデータを共有する

この例では、Arcを使って複数のスレッドから同じ共有データに安全にアクセスし、読み取る方法を示します。各スレッドは独自の`Arc`クローンを取得します。

メインスレッドは、生成したすべてのスレッドが完了するまで待機します。

use std::sync::Arc;
use std::thread;

fn main() {
  let data = Arc::new(vec![1, 2, 3, 4, 5]);
  let mut handles = vec![];

  for i in 0..3 {
    let data_clone = Arc::clone(&data); // Clone Arc for each thread
    let handle = thread::spawn(move || {
      println!("Thread {} has data: {:?}", i, *data_clone);
    });
    handles.push(handle);
  }

  for handle in handles {
    handle.join().unwrap();
  }
  println!("All threads finished.");
}

Box、Rc、Arcの使い分け

適切なスマートポインターは、用途に応じて選択します。

  • Box<T>:データをヒープに置く必要がある場合。通常は単一所有権で使う場合や、再帰的な型を扱う場合です。
  • Rc<T>:単一スレッドのコンテキストで、データに複数の所有者が必要な場合。
  • Arc<T>:マルチスレッド(並行処理)のコンテキストで、データに複数の所有者が必要な場合。

スレッドセーフ性が必要ない場合は、常にBoxまたはRcを優先してください。Arcにはパフォーマンス上のコストがあるためです。

スマートポインターの確認

大きな画像ファイルをヒープに格納し、プログラムの一部分だけがその所有と管理を行う必要があります。どのスマートポインターを使うべきでしょうか。

まとめ:スマートポインター

このレッスンでは、Rustの基本的なスマートポインターを3つ学びました。

  • Box<T>:単一所有権でデータをヒープに割り当てるために使用します。
  • Rc<T>:単一スレッド環境で、データに複数の所有者を持たせるために使用します。
  • Arc<T>:マルチスレッド環境で、スレッドセーフな複数の所有者を持たせるために使用します。

これらのスマートポインターを使うと、Rustの安全性を活用しながら、メモリ管理をより細かく制御できます。

よくある質問

「Box、Rc、Arcスマートポインタ」レッスンは無料ですか?

はい。「Box、Rc、Arcスマートポインタ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全3レッスンが含まれています。

「Box、Rc、Arcスマートポインタ」で何を学びますか?

ヒープ確保を行う`Box`、共有所有権を実現する`Rc`、スレッドセーフな共有所有権を実現する`Arc`によるデータ管理を理解します。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。

「Box、Rc、Arcスマートポインタ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Box、Rc、Arcスマートポインタ
  2. 内部可変性:RefCell、Cell
  3. スレッドによる恐れのない並行処理
← Learn Rust Codingに戻る