为什么类似 Deref 的特征不能组合?

问题描述 投票:0回答:1

在此代码中,

MyDeref
与标准库中
Deref
的定义匹配,并且
MemoryView
(从更复杂的示例简化而来)也几乎如此。

pub trait MyDeref {
    type Target: ?Sized;
    fn deref<'a>(&'a self) -> &'a Self::Target;
}

pub trait MemoryView {
    type T;
    fn at_ref<'a>(&'a self) -> &'a Self::T;
}

我期望这些特征能够组合起来,这样我就可以编写

MemoryView
的全面实现,涵盖任何取消引用
MemoryView
的类型:

impl<V: MemoryView, T: MyDeref<Target=V>> MemoryView for T {
    type T = V::T;
    fn at_ref<'a>(&'a self) -> &'a Self::T {
        self.deref().at_ref()
    }
}

但是,我收到编译器错误:

error[E0309]: the parameter type `V` may not live long enough
  --> src/lib.rs:14:9
   |
14 |         self.deref().at_ref()
   |         ^^^^^^^^^^^^ ...so that the type `V` will meet its required lifetime bounds

似乎是在说方法签名暗示

Self
Self::T
'a
寿命更长,但并不是说
Self::Target
a
寿命更长。

我很难想象

Self::Target
的寿命怎么会比
Self
短。对于明显的
Deref
类型,例如
&'a Target
Box<Target>
,这是不可能的。

我也在努力写出某种特征界限,表明

Self::Target
Self
寿命更长。

这种全面实施感觉应该是可能的。救命!

rust traits lifetime borrow-checker
1个回答
0
投票

这是您做错事情的情况之一,导致编译器非常困惑,以至于建议您做一些无助于解决根本问题的事情。

您可以让此错误消失(否则不必要的生命周期 GAT),然后允许编译器揭示真正的问题:

V
不受
MemoryView for T
实现的限制。因为
V
不受约束,所以编译器无法真正了解它与其他生命周期的关系,从而推断出
V
的适当生命周期...即使您可以解决此问题,也无法拥有不受约束的生命周期泛型类型参数无论如何所以这是一个有争议的问题。

解决方案是完全删除

V
参数。您在这里使用它的唯一原因是限制
T::Target
实现
MemoryView
- 所以只需添加该界限,然后在实现中适当调整
type T

impl<T: MyDeref> MemoryView for T
where
    <T as MyDeref>::Target: MemoryView,
{
    type T = <<T as MyDeref>::Target as MemoryView>::T;

    fn at_ref<'a>(&'a self) -> &'a Self::T {
        self.deref().at_ref()
    }
}

(游乐场)

© www.soinside.com 2019 - 2024. All rights reserved.