为什么我不能在特定的生命周期内实现 Deref?

Why can't I implement Deref for a specific lifetime?

use std::ops::{Deref};
use std::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<T>;

    fn deref(&'a self) -> &'a Self::Target {
        &self.mutex_guard.deref().as_ref().map(|x|*x)
    }
}

这给出:

   = note: expected fn pointer `fn(&MutexGuardRef<'a, T>) -> &Option<T>`
              found fn pointer `fn(&'a MutexGuardRef<'a, T>) -> &'a Option<T>`

为什么我不能在特定的生命周期内实现特征?为什么一定要一辈子?

您的代码有两个问题需要解决。

终生

Why I cannot implement a trait for a specific lifetime? Why it has to be all lifetimes?

在特定的生命周期内实现特征没有问题,如 impl<'a, T> Deref for MutexGuardRef<'a, T>。事实上,这是正确的做法。当您实现 deref 方法时出现编译器错误。

我认为这里的混淆是由于对类型的生命周期界限的误解造成的,例如 MutexGuardRef<'a, T> 中的 'a'a 并不意味着 MutexGuardRef<'a, T> 类型的每个值都在 'a 期间存在;相反,它意味着 type 本身受 'a 限制,这意味着 每个 value'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 到 return 一个 Option<&T>,它指向包含在互斥体中的最里面的 T(如果有的话)。但是,Deref 特征指示 return 类型的形式为 &Self::Target,因此我们最好的调用是 return &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)