ドロップガード

Rust における ドロップガード とは、スコープを抜けるときに何らかの クリーンアップ処理を行う一時オブジェクトです。Mutex の場合、lock メソッドは drop 時にミューテックスを自動的にアンロックする MutexGuard を返します。

// 著作権 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

struct Mutex {
    is_locked: bool,
}

struct MutexGuard<'a> {
    mutex: &'a mut Mutex,
}

impl Mutex {
    fn new() -> Self {
        Self { is_locked: false }
    }

    fn lock(&mut self) -> MutexGuard<'_> {
        self.is_locked = true;
        MutexGuard { mutex: self }
    }
}

impl Drop for MutexGuard<'_> {
    fn drop(&mut self) {
        self.mutex.is_locked = false;
    }
}
  • 上の例は、単純化した Mutex と、それに対応するガードを示しています。

  • これは実運用向けの実装ではありませんが、中核となる考え方を示しています。

    • ガードは排他的アクセスを表し、
    • その Drop 実装は、スコープを抜けるときにロックを解放します。

さらに掘り下げる

この例では、保護対象のデータを内部に保持しない C++ スタイルのミューテックスを 示しています。これは Rust では慣用的ではありませんが、ここでの目的は 適切な Rust のミューテックス設計を示すことではなく、ドロップガードの 中核となる考え方を説明することだけです。

簡潔さのために、いくつかの機能は省かれています。

  • 実際の Mutex<T> は、保護される値をミューテックス内部に保持します。
    この簡易的な例では、ドロップガードの仕組みだけに焦点を当てるため、 値そのものを完全に省いています。
  • MutexGuard に対する DerefDerefMut による使いやすいアクセス (ガードを &T または &mut T のように扱えるようにすること)。
  • 完全にブロッキングする .lock() メソッドと、非ブロッキングな try_lock バリアント。

実運用向けミューテックスの例として、 Rust の std ライブラリにある Mutex の実装 を参照できます。また、 parking_lot クレートの Mutex も参考になります。