为什么我不能在特定的生命周期内实现 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
}
}
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
}
}