您的代码有两个问题需要解决。
终身
为什么我不能在特定的生命周期内实现特征?为什么必须
一辈子?
在特定生命周期内实现特征没有问题,如impl<'a, T> Deref for MutexGuardRef<'a, T>。事实上,这是正确的做法。实现deref 方法时会出现编译器错误。
我认为这里的混淆是由于对类型的生命周期界限的误解造成的,例如MutexGuardRef<'a, T> 中的'a。 'a 并不意味着MutexGuardRef<'a, T> 类型的每个值都存在于'a 期间;相反,这意味着 type 本身以'a 为界,这意味着 每个 value 最多存在 /em> 在'a 的持续时间内。我们将此称为限制 1。
另一方面,当您写下&'a self(self: &'a MutexGuardRef<'a, T> 的缩写)时,您是在说引用self 指向的*self 是一个值 在'a 期间有效;换句话说,它是一个值,它在'a 的持续时间内存在至少,我们将其称为限制 2.
我希望这个解释能让事情变得更清楚——限制 1 是必要的,因为它是类型的固有属性;但是,限制 2 并不是我们要寻找的,因为取消引用 MutexGuardRef 值并不要求它像 Mutex 一样长。
当我们从 deref 的实现中删除两个出现的 'a 时,我们得到
fn deref(&self) -> &Self::Target
简称
fn deref(self: &MutexGuardRef<'a, T>) -> &Self::Target
限制 1 被保留,而限制 2 被解除。因此编译器很满意...
类型
...除了它向我们打招呼另一个错误:
error[E0308]: mismatched types
--> src/lib.rs:12:9
|
8 | impl<'a, T> Deref for MutexGuardRef<'a, T> {
| - this type parameter
...
12 | &self.mutex_guard.deref().as_ref().map(|x|*x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `Box`
|
= note: expected reference `&Option<T>`
found reference `&Option<Box<T>>`
揭示不同类型的问题。
&Self::Target,代表&Option<T>,是对已经存在的Option<T> 的引用。我们只有一个Mutex<Option<Box<T>>>——没有Option<T>可以指向。
理想情况下,我们希望deref 返回一个Option<&T>,它指向包裹在互斥锁中的最里面的T(如果有)。然而,Deref trait 规定返回类型为&Self::Target,所以我们最好的调用是返回&Option<Box<T>>。
结果:
use std::{ops::Deref, sync::MutexGuard};
pub struct MutexGuardRef<'a, T> {
mutex_guard: MutexGuard<'a, Option<Box<T>>>,
}
impl<'a, T> Deref for MutexGuardRef<'a, T> {
type Target = Option<Box<T>>;
fn deref(&self) -> &Self::Target {
&*self.mutex_guard
}
}
(playground)