web-dev-qa-db-ja.com

Rustのセルと参照カウントタイプについての全体的な説明が必要

Rust標準ライブラリにはいくつかのラッパータイプがあります。

私が理解しているように、これらはラッパーであり、単純な参照よりもさらなる可能性を提供します。いくつかの基本を理解していますが、全体像を見ることができません。

彼らは正確に何をしますか?セルと参照カウントファミリは、直交または類似の機能を提供しますか?

64

Rustには2つの基本的な概念があります。

  • 所有権、
  • 可変性。

さまざまなポインタータイプ(BoxRcArc)はOwnershipに関係しています。単一のオブジェクトの所有者が単一か複数かを制御できます。

一方、さまざまなセル(CellRefCellMutexRwLockAtomicXXX)は可変性


Rustの安全性の基礎となるルールは、Aliasing XOR Mutabilityです。つまり、オブジェクトは、その内部への顕著な参照がない場合にのみ安全に変更できます。

このルールは通常、コンパイル時に借用チェッカーによって実施されます。

  • &Tがある場合、スコープ内の同じオブジェクトに対して&mut Tを使用することはできません。
  • &mut Tがある場合、スコープ内の同じオブジェクトへの参照もできません。

ただし、これには十分な柔軟性がない場合があります。時には、同じオブジェクトへの複数の参照を持ちながら、それを変更する機能が必要な(または必要な)場合があります。 cellsを入力します。

CellRefCellの考え方は、エイリアスの存在下で、制御された方法で可変性を許可することです。

  • Cellは、内部への参照の形成を防ぎ、ぶら下がり参照を回避します。
  • RefCellは、コンパイル時からランタイムにAliasing XOR Mutabilityの強制を変更します。

この機能は、interior mutabilityを提供すると説明される場合があります。これは、外部からは不変に見えるオブジェクト(&T)を実際に変更できる場所です。

この可変性が複数のスレッドにまたがる場合、代わりにMutexRwLockまたはAtomicXXX;を使用します。それらは同じ機能を提供します:

  • AtomicXXXは単なるCellです。内部への参照はなく、単に出入りします。
  • RwLockRefCellだけです:guardsを介して内部への参照を取得できます。
  • MutexRwLockの簡易バージョンであり、読み取り専用ガードと書き込みガードを区別しません。 borrow_mutメソッドのみを持つRefCellに概念的に似ています。

C++のバックグラウンドから来た場合:

  • Boxunique_ptrです、
  • Arcshared_ptrです、
  • Rcは、shared_ptrの非スレッドセーフバージョンです。

また、セルはmutableと同様の機能を提供しますが、エイリアスの問題を回避するための追加の保証があります。 Cellstd::atomicと見なし、RefCellstd::shared_mutexのスレッドセーフでないバージョンと見なします(ロックが取得されると、ブロックする代わりにスローされます)。

120
Matthieu M.

Matthieuの良い答え のおかげで、必要なラッパーを見つけるのに役立つ図を以下に示します。

+-----------+
| Ownership |
+--+--------+                              +================+
   |                         +-Static----->| T              |(1)
   |                         |             +================+
   |                         |
   |                         |             +================+
   |          +-----------+  | Local    Val| Cell<T>        |(1)
   +-Unique-->| Borrowing +--+-Dynamic---->|----------------|
   |          +-----------+  |          Ref| RefCell<T>     |(1)
   |                         |             +================+
   |                         |
   |                         |             +================+
   |                         | Threaded    | AtomicT        |(2)
   |                         +-Dynamic---->|----------------|
   |                                       | Mutex<T>       |(1)
   |                                       | RwLock<T>      |(1)
   |                                       +================+
   |
   |
   |                                       +================+
   |                         +-No--------->| Rc<T>          |
   |                         |             +================+
   | Locally  +-----------+  |
   +-Shared-->| Mutable?  +--+             +================+
   |          +-----------+  |          Val| Rc<Cell<T>>    |
   |                         +-Yes-------->|----------------|
   |                                    Ref| Rc<RefCell<T>> |
   |                                       +================+
   |
   |
   |                                       +================+
   |                         +-No--------->| Arc<T>         |
   |                         |             +================+
   | Shared   +-----------+  |
   +-Between->| Mutable?  +--+             +================+
     Threads  +-----------+  |             | Arc<AtomicT>   |(2)
                             +-Yes-------->|----------------|
                                           | Arc<Mutex<T>>  |
                                           | Arc<RwLock<T>> |
                                           +================+
  1. これらの場合、TBox<T>に置き換えることができます
  2. 使用する AtomicTTboolまたは数値の場合

MutexRwLockのどちらを使用すべきかを知るには、 この関連する質問 を参照してください。

6