为什么 Deref 样的特征不组成?

Why don't Deref-like traits compose?

提问人:apt1002 提问时间:11/2/2023 更新时间:11/2/2023 访问量:80

问:

在此代码中,与标准库中的定义相匹配,并且(从更复杂的示例中简化)几乎也是如此。MyDerefDerefMemoryView

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;
}

我希望这些特征能够组合在一起,这样我就可以编写一个涵盖任何类型的一揽子实现,这些类型取消了对 :MemoryViewMemoryView

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'aSelf::Targeta

我很难想象 a 的寿命怎么会比 .对于明显的类型(例如 和 )是不可能的。Self::TargetSelfDeref&'a TargetBox<Target>

我也在努力写某种特征绑定,说寿命比 .Self::TargetSelf

这种一揽子实现感觉应该是可能的。帮助!

寿命 借用检查器

评论


答:

7赞 cdhowie 11/2/2023 #1

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

您可以使用(否则不必要的)生存期 GAT 来消除此错误,这样编译器就可以揭示真正的问题:在实现中不受约束。因为不受约束,编译器无法真正看到它与其他生存期的关系,无法推断出 ...即使你可以解决这个问题,你不能有一个不受约束的泛型类型参数,所以这是一个有争议的问题。VMemoryView for TVV

解决方案是完全删除该参数。你在这里使用它的唯一原因是,你可以要求实现 -- 所以只需添加该边界,然后相应地调整实现:VT::TargetMemoryViewtype 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()
    }
}

(操场)