假设有一个典型的GAT示例,引用迭代器:

#![feature(generic_associated_types)]
use std::ops::Deref;

trait MyIterator {
    type Item<'a>
    where
        Self: 'a;
    fn next(&mut self) -> Self::Item<'_>;
}

例如,我可以用Box<T>美元实现这个功能.

// This is OK
impl<U> MyIterator for Box<U> {
    type Item<'a> = &'a U
    where
        Self: 'a;
    fn next(&mut self) -> Self::Item<'_> {
        <Box<T> as Deref>::deref(self)
    }
}

但当我用Deref个特征来概括它时就不是了:

// error[E0309]: the parameter type `U` may not live long enough
impl<T, U> MyIterator for T
where
    T: Deref<Target = U>,
{
    type Item<'a> = &'a U
    where
        Self: 'a;
    fn next(&mut self) -> Self::Item<'_> {
        <T as Deref>::deref(self)
    }
}

据我所知,在Box<T>种情况下,编译器不知何故知道U类型属于Box<U>,因此U的生命周期 肯定比Box<U>长.如果是Box<U>: 'a,那么编译器可以说是U: 'a.

但这种逻辑在Deref<Target=U>的情况下不起作用,即使Derefderef(&self) -> &Self::Target个方法,这意味着在任何生命周期中,T: 'a就是U: 'a.

我如何告诉编译器后一种情况实际上是安全的?

推荐答案

问题是,您正在将both TU转换为独立的类型参数,但实际上U总是由T唯一确定的.

而使用TDeref::Target类型是really的意思,这也使得类型判断器更容易推断生命周期 .

impl<T> MyIterator for T
where
    T: Deref,
{
    type Item<'a> = &'a <T as Deref>::Target
    where
        Self: 'a;
    fn next(&mut self) -> Self::Item<'_> {
        <T as Deref>::deref(self)
    }
}

Rust相关问答推荐

无法在线程之间安全地发送future (&Q;)&错误

Rust:跨多个线程使用hashmap Arc和rwlock

在自身功能上实现类似移动的行为,以允许通过大小的所有者进行呼叫(&;mut;self)?

铁 rust 中的泛型:不能将`<;T作为添加>;::Output`除以`{Float}`

如何将单个 struct 实例与插入器一起传递到Rust中的映射

为什么Deref类特征不构成?

在macro_rule中拆分模块和函数名

无法将 rust 蚀向量附加到另一个向量

为什么 tokio 在以奇怪的方式调用时只运行 n 个任务中的 n-1 个?

为什么Rust中无法推断生命周期?

如何为已实现其他相关 std trait 的每个类型实现一个 std Trait

Rust 打包在 .deb 中

简单 TCP 服务器的连接由对等重置错误,mio 负载较小

从嵌入式 Rust 中的某个时刻开始经过的时间

我如何将特征作为 struct 的拥有字段?

Rust,我如何正确释放堆分配的内存?

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

相交着色器从 SSBO 中读取零

有没有办法在 Rust 中对 BigInt 进行正确的位移?

返回 &str 但不是 String 时,borrow 时间比预期长