互斥量的锈访问选项

问题描述 投票:0回答:1

我在理解如何修改互斥对象中的Option时遇到麻烦。

没有选项时,它可以正常工作

let mut my_int = Arc::new(Mutex::new(5));

let my_int_clone = Arc::clone(&my_int);

thread::spawn(move || {
  let mut my_int = my_int_clone.lock().unwrap();
  *my_int += 1;
}).join();

let my_int_clone_print = Arc::clone(&my_int);
println!("Value: {}", my_int_clone_print.lock().unwrap());

但是,当我将值包装在Some中时,我不得不手动使用ref mut之类的东西(我从here中找到了它),因为lock().unwrap()返回了MutexGuard,而不是Option本身。

let mut my_int = Arc::new(Mutex::new(Some(5)));

let my_int_clone = Arc::clone(&my_int);

thread::spawn(move || {
  let mut my_int = my_int_clone.lock().unwrap();

  match *my_int {
    Some(ref mut val) => {
      *val += 1;
    },
    None => {
      println!("Value is None. Doing nothing..");
    }
  }

}).join();

let my_int_clone_print = Arc::clone(&my_int);
println!("Value: {}", my_int_clone_print.lock().unwrap());

有哪个Rust概念引起这个想法?除了Option以外,还有其他数据类型返回MutexGuard而不是其原始值吗?

concurrency rust mutex
1个回答
0
投票

实际上,在两种情况下均为Mutex::lockreturnsResult<MutexGuard, ..>。但是,此类型具有有趣的特征实现:DerefDeref。这些允许通过在第一个示例中使用的DerefMut运算符进行显式取消引用。考虑一下带有显式类型的示例:

DerefMut

当然,您也可以类似地使用*

let mutex = Mutex::new(1i32);
let mut guard: MutexGuard<'_, i32> = mutex.lock().unwrap();

// This dereferences to &mut i32 
// because assignment operator works with &mut self.
*guard = 2;

// Nevertheless, for an explicit borrowing you need &mut
// because otherwise it would be moved from the guard.
let inner: &mut i32 = &mut *guard;

注意,最后一个匹配示例与您的完全相同,只是更通用。 Option

© www.soinside.com 2019 - 2024. All rights reserved.