为什么Deref类似的特质不能组合在一起?

4
在这段代码中,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

看起来它在说方法签名暗示了SelfSelf::T的生命周期比'a长,但不意味着Self::Target的生命周期比a长。

我很难想象Self::Target的生命周期如何比Self更短。对于明显的Deref类型,比如&'a TargetBox<Target>,这是不可能的。

我也很难写出某种特质约束,表明Self::Target的生命周期比Self长。

这个通用实现感觉应该是可能的。帮帮忙!

1个回答

7
这是其中一种情况,你以一种错误的方式做事情,以至于编译器感到困惑,建议你做一些对解决潜在问题没有帮助的事情。
你可以通过(本来不必要的)生命周期GATs来消除这个错误,这样编译器就能揭示真正的问题:在T的MemoryView实现中,V没有受到约束。因为V没有受到约束,编译器无法真正看到它与其他生命周期的关系,从而推断出适当的生命周期...即使你能修复这个问题,你也不能有一个无约束的泛型类型参数,所以这是一个无关紧要的问题。
解决方案是完全删除V参数。你在这里使用它的唯一原因是要求T::Target实现MemoryView - 所以只需添加该约束,并相应地调整实现中的type T即可。
impl<T> MemoryView for T
where
    T: MyDeref,
    <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()
    }
}

游乐场

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接