[英]Lifetime issue when wrapping a function returning an Iterator
I am building a custom data structure which supposes to return an iterator for its elements.我正在构建一个自定义数据结构,它应该为其元素返回一个迭代器。 If simplified, it can look like this:如果简化,它可能看起来像这样:
use std::iter::{Iterator, StepBy};
// My collection which returns iterator to it's elements
pub trait MyCollection<'a, T: 'a> {
type I: Iterator<Item = &'a T>;
fn find_something(&'a self) -> Self::I;
}
Now, in some cases, I would like to create a "wrapper" for this collection that transforms the elements returned by the iterator.现在,在某些情况下,我想为这个集合创建一个“包装器”,用于转换迭代器返回的元素。 For the sake of this example let's assume that this wrapper allows skipping over some elements of the original iterator:为了这个例子,我们假设这个包装器允许跳过原始迭代器的一些元素:
// Wrapper for a collection that allows iterating over elements with a step
pub struct StepWrapper<'a, A>(&'a A, usize);
impl<'a, T: 'a, A: MyCollection<'a, T>> MyCollection<'a, T> for StepWrapper<'a, A> {
type I = StepBy<A::I>;
fn find_something(&'a self) -> Self::I {
self.0.find_something().step_by(self.1)
}
}
// Function which takes a collection and a step value and returns a wrapped collection
fn wrap<'a, T: 'a, A: MyCollection<'a, T>>(a: &'a A, step: usize) -> impl MyCollection<'a, T> {
StepWrapper(a, step)
}
Unfortunately, I get a compilation error when trying to use this code:不幸的是,尝试使用此代码时出现编译错误:
// Example
impl<'a> MyCollection<'a, u64> for Vec<u64> {
type I = std::slice::Iter<'a, u64>;
fn find_something(&'a self) -> Self::I {
return self.iter();
}
}
fn main() {
let collection = vec![12, 13, 14];
let wrapped = wrap(&collection, 2);
// Error now
let result = wrapped.find_something().skip(1).next();
// ^^^^^^^ borrowed value does not live long enough
println!("{}", result.unwrap());
}
I understand that StepWrapper<'a, A>::find_something
requires self
to be borrowed for the same lifetime as the original collection.我了解StepWrapper<'a, A>::find_something
要求在与原始集合相同的生命周期内借用self
。 But all my attempts to decouple lifetimes of a collection and a wrapper were unuseful.但是我所有将集合和包装器的生命周期解耦的尝试都是无用的。 Essentially a find_something
function in the wrapper needs to return a result which outlives itself.本质上,包装器中的find_something
function 需要返回一个超过自身寿命的结果。 Is there a way to express it in Rust?有没有办法用Rust来表达?
The pattern you're using is called a streaming iterator , and unfortunately it's not possible with the Iterator
trait.您正在使用的模式称为流式迭代器,不幸的是,使用Iterator
特征是不可能的。
This is a current weakness of Rust's type system: it lacks what are known as generic associated types, or GATs.这是 Rust 类型系统当前的一个弱点:它缺少所谓的泛型关联类型或 GAT。 There's an RFC for this language feature and a tracking issue . 此语言功能有一个 RFC和一个跟踪问题。
In the meantime, the streaming_iterator
crate is designed to provide the functionality you're looking for.同时, streaming_iterator
crate旨在提供您正在寻找的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.