内部可変型では、可変指定がなくても、特例として値を変更できる。
これが安全に行えるのは、他の参照と干渉しない特定のパターンに限られる。
内部可変型を利用すると、本質的でない可変参照による排他性を除去できる。
標準で提供される内部可変型について。
UnsafeCell
UnsafeCell は仕様上の特別な型で、ここで紹介しているその他の型の実装の基盤にもなっている。コンパイラはこの型でラップされた値については、たとえ不変とマークされていても、変更されうるものとして扱う。
UnsafeCell 以外
UnsafeCell をそのまま使うのはお勧めできない。なぜなら、それは普段ならば Rust が保証してくれる読込と書込の排他性、それから書込と書込の排他性を失わせる。そのため、バグを書きやすくなる。一方、UnsafeCell を利用して実装された標準型では、他の参照との干渉がおきない理論的背景がある。そのため、可能な限りそれらを採用した方がよい。
UnsafeCell
Cell
OnceCell
LazyCell
RefCell
OnceLock
OnceCell の非同期版)。
LazyLock
LazyCell の非同期版)。
Mutex
RwLock の簡易版)。
RwLock
RefCell の非同期版)。
AtomicXXX
AtomicI32 や AtomicU32 など)。
以下では、変数 cell に mut の指定はないが、値を変更できる。
use std::cell::Cell;
fn main() {
let cell = Cell::new(42);
cell.set(43);
assert_eq!(cell.get(), 43);
}