简体   繁体   English

爬入结构类型的迭代器的通用生命周期参数

[英]Generic lifetime parameter of the iterator creeping into the struct type

I am trying to create a data structure (let's call it Outer ) that wraps another data structure (let's call it Inner ).我正在尝试创建一个包装另一个数据结构(我们称之为Inner )的数据结构(我们称之为Outer )。 However, rather than fixing an implementation for Inner , I want to use a trait so that I can easily swap the implementation of this underlying data structure.但是,我不想修复Inner的实现,而是想使用一个特征,以便我可以轻松地交换这个底层数据结构的实现。

A simplified version would look somewhat like this:简化版本看起来有点像这样:

pub struct Outer<K, V, I>
where
    I: Inner<K, V>
{
    inner: I,
    // some phantom data fields
}

pub trait Inner<K, V>
{
    ...
}

Now, I want to add an iterator to Outer which should also wrap an iterator provided by the inner data structure, and here comes the problem.现在,我想向Outer添加一个迭代器,它还应该包装内部数据结构提供的迭代器,问题就来了。

In the Inner trait, I cannot write: Inner在特质中,我不能写:

fn iter(&self) -> impl Iterator<Item = (&'_ K, &'_ V)>;

as impl Trait syntax is not allowed here, and I also cannot introduce an associated type like:因为这里不允许使用impl Trait语法,我也不能引入如下关联类型:

type Iterator<'a>: Iterator<Item = (&'a K, &'a V)>;

since generic associated types are not there yet.因为还没有泛型关联类型

What I came up with so far is to have a separate trait for an iterator:到目前为止,我想出的是为迭代器提供一个单独的特征:

pub trait InnerIterator<'a, K: 'a, V: 'a>: Iterator<Item = (&'a K, &'a V)> {
    type Inner: Inner<K, V>;

    fn new(inner: &'a Self::Inner) -> Self;
}

Then Outer receives a new generic type parameter InnerIt :然后Outer接收一个新的泛型类型参数InnerIt

pub struct Outer<K, V, I, InnerIt>
where
    I: Inner<K, V>
{
    inner: I,
    // some phantom data fields
}

impl<K, V, I, InnerIt> Outer<K, V, I, InnerIt> {
    pub fn iter<'a>(&'a self) -> InnerIt
    where
        I: Inner<K, V>,
        InnerIt: InnerIterator<'a, K, V, Inner = I>,
        K: 'a,
        V: 'a,
    {
        InnerIt::new(&self.inner)
    }
}

And now, when I want to pick some specific Inner implementation, I have something like:现在,当我想选择一些特定的Inner实现时,我有类似的东西:

pub type SomeOuter<'a, K, V> = Outer<K, V, SomeInner<K, V>, SomeInnerIterator<'a, K, V>>;

and here the lifetime parameter 'a becomes a part of my type definition.在这里,生命周期参数'a成为我的类型定义的一部分。

Other than the problem that I would have to add at least two more parameters for enabling iter_mut and into_iter , my question is what would be the consequences of having this 'a parameter there, would it continue to propagate further when using this type, would the user of this type be surprised by this lifetime parameter, and is there a way to implement iterators without introducing generic iterator types and their lifetimes for Outer ?除了我必须添加至少两个参数来启用iter_mutinto_iter的问题之外,我的问题是,在此处使用此'a参数会产生什么后果,在使用此类型时它会继续进一步传播吗?这种类型的用户对这个生命周期参数感到惊讶,有没有办法在不引入通用迭代器类型及其生命周期的情况下实现迭代器Outer

would it continue to propagate further when using this type使用这种类型时会继续传播吗

Any type that wants to embed your type would need to also have a lifetime parameter.任何想要嵌入你的类型的类型都需要有一个生命周期参数。 However, some places lifetime elision will take over (eg in function arguments):然而,在某些地方,生命周期省略会接管(例如在 function 参数中):

struct Struct1<'a>(std::marker::PhantomData<&'a ()>);
struct Struct2<'a>(Struct1<'a>); // lifetime propagates to Struct2

fn func(_: Struct1){
    println!("lifetime not needed. It is 'elided'");
}

would the user of this type be surprised by this lifetime parameter这种类型的用户会对这个生命周期参数感到惊讶吗

They shouldn't be.他们不应该。 In rust, lifetime are everywhere.在 rust 中,生命周期无处不在。 For example, iterating over a slice is done using a struct with a lifetime parameter .例如,对切片的迭代是使用具有生命周期参数的结构完成的。

is there a way to implement iterators without introducing generic iterator types and their lifetimes for Outer?有没有一种方法可以在不引入通用迭代器类型及其外部生命周期的情况下实现迭代器?

The reason why you have a lifetime parameter is that you have an iterator that returns a reference.你有一个生命周期参数的原因是你有一个返回引用的迭代器。 If your iterator would return a direct object no lifetime would be needed.如果您的迭代器将返回直接 object 则不需要生命周期。 For example, if you turn a vector into an iterator (which thus returns all the elements in the vector) it won't need a lifetime parameter例如,如果您将向量转换为迭代器(从而返回向量中的所有元素) ,则不需要生命周期参数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM