内部可変性のある型の get_mut 関数と from_mut 関数について。

基礎知識

内部可変性のある型』では、可変と指定されていなくても、特例として値を変更できる。

しかし、これだと普段は Rust が保証してくれる読込と書込の排他性、それから書込と書込の排他性が保証されなくなってしまう。そのため、それらの型では独自のルールで別途それらの排他性を保証している場合が多い。例えば、RefCell 型ではその内部値へのアクセス前に、競合する操作を他で実行中でないか、動的に確認するようになっている。

get_mut 関数

上記のように、内部可変性のある型では、各操作の排他性の保証のために独自のルールを持つものが多い。しかし、内部可変性のある型への可変参照がある場合、もはやそのルールに従わなくてもよい。なぜなら、可変参照は参照先の専有を意味しているからである。

そのため、内部可変性のある型では、その可変参照からは値を自由に操作できるよう、get_mut という名称の関数がある場合が多く、そこから内部の値への可変参照が得られる。

以下は get_mut 関数の代表例である。

UnsafeCell<T> fn get_mut(&mut self) -> &mut T
Cell<T> fn get_mut(&mut self) -> &mut T
OnceCell<T> fn get_mut(&mut self) -> Option<&mut T>
RefCell<T> fn get_mut(&mut self) -> &mut T
OnceLock<T> fn get_mut(&mut self) -> Option<&mut T>
Mutex<T> fn get_mut(&mut self) -> LockResult<&mut T>
RwLock<T> fn get_mut(&mut self) -> LockResult<&mut T>

from_mut 関数

from_mut 関数は get_mut 関数の逆操作にあたる。

なお、from_mut 関数を提供する型は、get_mut 関数を提供する型に比べると少ない。これは元となる内部値への可変参照だけでは、目的の内部可変型の材料として不足するためである (例えば、RefCell 型では、それが読込中か書込中かなどの制御情報がある)。

以下は from_mut 関数の代表例である。

UnsafeCell<T> fn from_mut(value: &mut T) -> &mut UnsafeCell<T>
Cell<T> fn from_mut(t: &mut T) -> &Cell<T>

UnsafeCell::from_mutはナイトリー。