データを持つトークン型: MutexGuard

トークン型が追加のデータを必要とすることもあります。MutexGuard は、 権限 + データを表すトークンの一例です。

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

use std::sync::{Arc, Mutex, MutexGuard};

fn main() {
    let mutex = Arc::new(Mutex::new(42));
    let try_mutex_guard: Result<MutexGuard<'_, _>, _> = mutex.lock();
    if let Ok(mut guarded) = try_mutex_guard {
        // 取得した MutexGuard は、排他的アクセスの証明です。
        *guarded = 451;
    }
}
  • Mutex は、値への読み取り/書き込みアクセスに対して相互排他を強制します。すでに このコースの前半で Mutex は扱いましたが(参照: RAII/Mutex)、ここでは 特に MutexGuard を見ていきます。

  • MutexGuard は、ある時点で読み取り/書き込みアクセス権があることを証明する、 Mutex によって生成される値です。

    MutexGuard はさらに、それを生成した Mutex への参照も保持しており、 DerefDerefMut の実装によって、基盤となる Mutex がそのデータを ユーザーから非公開のまま、Mutex のデータにアクセスできます。

  • mutex.lock()MutexGuard を返さない場合、mutex 内の値を変更する 権限はありません。

    権限がないだけでなく、MutexGuard を得ない限り、mutex のデータにアクセスする 手段もありません。

    これは C++ と対照的です。C++ では、mutex と lock guard はデータ自体へのアクセスを 制御せず、単に、データを読むときや操作するときに毎回ユーザーが確認することを 覚えておかなければならないフラグとして機能するだけです。

  • 実演: mutex 変数を可変にしてから、それをデリファレンスして値を変更しようと してみてください。これには Deref 実装がなく、mutex guard を取得する以外に、 それが保持しているデータへ到達する方法がないことを示してください。