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

标签 rust traits 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 时,会出现编译器错误。方法。

我认为这里的困惑是由于对类型生命周期界限的误解造成的,例如 'aMutexGuardRef<'a, T>'a并不意味着 MutexGuardRef<'a, T> 类型的每个值生命周期为'a ;相反,这意味着 type 本身的边界是 'a ,这意味着每个最多存在'a的持续时间。 .我们将此称为限制 1

另一方面,当你写下 &'a self ,它是 self: &'a MutexGuardRef<'a, T> 的缩写,你是说*self ,其中引用self指向的值在 'a 的持续时间内有效;换句话说,它是一个至少存在 'a 的持续时间内。 ,我们将其称为限制 2

我希望这个解释能让事情变得更清楚——限制 1 是必要的,因为它是类型的固有属性;然而,限制 2 并不是我们正在寻找的,因为取消引用 MutexGuardRef值并不要求它的生存时间与Mutex一样长。确实如此。

当我们删除两个出现的 'a 时从执行deref ,我们得到

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特征规定返回类型的形式为 &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 )

关于rust - 为什么我不能在特定的生命周期内实现 Deref?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68138511/

相关文章:

c++ - Rust 是否像 C++ 一样在索引时隐式创建映射条目?

rust - 如何在不消耗值的情况下实现添加特征

c++ - 从另一个线程访问具有自动存储持续时间的对象

rust - 如何为实现另一个特征的类型实现特征而不冲突的实现

scala:重用子类实现作为两个不同类的子类?

c++ - 避免未定义的行为 : temporary objects

rust - 如何在 Rust 中通过借用来正确管理所有权?

reference - 为什么特征实现不针对结构进行编译,而是针对结构的引用进行编译?

indexing - 我如何为不存储值本身的类型实现 IndexMut

struct - 如何仅将某些结构成员设置为其默认值?