解锁互斥锁不会返回`MutexGuard`

时间:2021-07-03 22:22:50

标签: rust

在下面的代码中:

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

pub struct MutexGuardOptionRef<'a, T: ?Sized> {
    pub mutex_guard: MutexGuard<'a, Option<Box<T>>>,
}

pub trait LockableOption<T: ?Sized> {
    fn lock(&self) -> LockResult<MutexGuardOptionRef<T>>;
}

pub type LockableArc<T> = Arc<Mutex<Option<T>>>;

impl<T> LockableOption<T> for LockableArc<Box<T>> {
    fn lock(&self) -> LockResult<MutexGuardOptionRef<T>> {
        let mutex_guard = self.lock();
        match mutex_guard {
            Ok(m) => Ok(MutexGuardOptionRef{
                mutex_guard: m
            }),
            _ => unimplemented!()
        }
    }
}

Playground

我们有

impl<T> LockableOption<T> for LockableArc<Box<T>> {
    fn lock(&self) -> LockResult<MutexGuardOptionRef<T>> {

因为我们正在为 LockableArc<Box<T>> 实现,那么 self: LockableArc<Box<T>>,所以调用 self.lock() 会调用 LobkcableArc::lock,它是 Mutex::lock,它应该给 {{1} },但它说它给了 MutexGuard:

错误:

MutexGuardOptionRef

发生了什么?

1 个答案:

答案 0 :(得分:2)

您看到此问题的原因是您的 self.lock 调用实际上是递归的。即 self.lock() 调用 LockableArc<Box<T>::lock,而不是 lock 上的 Mutex 方法。因此,m 的类型是 MutexGuardOptionRef,而不是 MutexGuard<'a, Option<Box<T>>。如果您将 mutex_guard: m 更改为 mutex_guard: m.mutex_guard,编译器会警告您此调用是无条件递归的。

显然,该更改将修复编译错误,但由于它总是会递归,因此您实际上不会想要这样做。相反,您可能需要更精确地指定要调用的方法,如 Mutex::lock(self),如下所示:

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

pub struct MutexGuardOptionRef<'a, T: ?Sized> {
    pub mutex_guard: MutexGuard<'a, Option<Box<T>>>,
}

pub trait LockableOption<T: ?Sized> {
    fn lock(&self) -> LockResult<MutexGuardOptionRef<T>>;
}

pub type LockableArc<T> = Arc<Mutex<Option<T>>>;

impl<T> LockableOption<T> for LockableArc<Box<T>> {
    fn lock(&self) -> LockResult<MutexGuardOptionRef<T>> {
        let mutex_guard = Mutex::lock(self);
        match mutex_guard {
            Ok(m) => Ok(MutexGuardOptionRef{
                mutex_guard: m
            }),
            _ => unimplemented!()
        }
    }
}

这既修复了无条件递归,又为您提供了您期望的类型的结果。

相关问题