Rustコトハジメ

プログラミング言語Rustに関する情報をお届けします。

Rustにおけるスマートポインタとは

https://www.rustforbeginners.com/entry/ja/2018/12/29www.rustforbeginners.com

で、Vecは3つのデータを持つ構造だと言った。そして、この時には所有権を持つ者ということで所有者という言葉を使った。

このように、内部に特殊なメタデータを持つポインタライクなものを、Rustではスマートポインタという。

Rustのスマートポインタの例としては、

  • ヒープ管理系: Box
  • リファレンスカウンタ系: Rc, Weak, Arc
  • ガード系; Ref, RefMut, MutexGuard, RwLockReadGuard, RwLockWriteGuard

がある。

これらをスマートポインタたらしめてる理由は、さきほどいった内部に特殊なメタデータを持っているという点と、それを利用した特殊なDropと、エルゴノミクスのためのDerefDerefMutが実装されている点だ。

例えば、MutexGuardのDropは、想像どおり、内部のロック機構に対してunlockを呼んでいる。

impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            self.__lock.poison.done(&self.__poison);
            self.__lock.inner.raw_unlock();
        }
    }
}

C++の経験がある人ならば、これに対して、C++でも同じようなことをするよというかもしれない。

void safe_increment()
{
    std::lock_guard<std::mutex> lock(g_i_mutex);
    ++g_i;
 
    std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
 
    // g_i_mutex is automatically released when lock
    // goes out of scope
}

その認識は正しくて、Rustはこれをトレイトとして一般化して言語仕様に組み込んだにすぎない。

C++でいうスマートポインタとしては、

  • unique_ptr
  • shared_ptr
  • weak_ptr

があるが、これらはRustではBox, Rc, Weakに相当する。これもやはり、C++では実装的全くかけ離れていたものを、同じスマートポインタという枠組みで一般化したにすぎない。