实现Streaming Iterator时的生命周期问题求解
关于Streaming Iterator中跨迭代器借用切片的生命周期问题
我正在用streaming iterators库构建一个运行时管道,迭代器类型是编译期未知的(比如流程是读取文件>解压gzip>解析内容>提取字段)。为了保证效率,跨迭代器借用切片是关键,但在实现对传入[u8]进行gzip解压的迭代器时,遇到了编译错误:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements --> src/main.rs:48:50 | 48 | self.reader = gzip::Decoder::new(self.it.next().unwrap()).ok(); | ^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 47:5... --> src/main.rs:47:5 | 47 | / fn advance(&mut self) { 48 | | self.reader = gzip::Decoder::new(self.it.next().unwrap()).ok(); 49 | | } | |_____^ note: ...so that reference does not outlive borrowed content --> src/main.rs:48:42 | 48 | self.reader = gzip::Decoder::new(self.it.next().unwrap()).ok(); | ^^^^^^^ note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 44:1... --> src/main.rs:44:1 | 44 | / impl<'a> StreamingIterator for GunzipIter<'a> { 45 | | type Item = gzip::Decoder<&'a [u8]>; 46 | | 47 | | fn advance(&mut self) { ... | 50 | | fn get(&self) -> Option<&gzip::Decoder<&'a [u8]>> { Some(&(self.reader.unwrap())) } 51 | | } | |_^ note: ...so that expression is assignable (expected std::option::Option<gzip::Decoder<&'a [u8]>>, found std::option::Option<gzip::Decoder<&[u8]>>) --> src/main.rs:48:23 | 48 | self.reader = gzip::Decoder::new(self.it.next().unwrap()).ok(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
库中可正常编译的示例
use streaming_iterator::StreamingIterator; pub struct FakeStreamingIterator<'a, I, T> where I: Iterator<Item = &'a &'a T>, T: 'a + ?Sized, { inner: Box<I>, current: Option<&'a &'a T>, } impl<'a, I, T> FakeStreamingIterator<'a, I, T> where I: Iterator<Item = &'a &'a T>, T: ?Sized, { fn new(inner: I) -> FakeStreamingIterator<'a, I, T> { FakeStreamingIterator { inner: Box::new(inner), current: None, } } } impl<'a, I, T> StreamingIterator for FakeStreamingIterator<'a, I, T> where I: Iterator<Item = &'a &'a T>, T: ?Sized, { type Item = T; fn advance(&mut self) { self.current = self.inner.next(); } fn get(&self) -> Option<&T> { self.current.map(|x| *x) } }
与我的用例更接近但无法编译的示例
use streaming_iterator::StreamingIterator; pub struct FakeStreamingIterator<'a> { inner: Box<StreamingIterator<Item = [u8]>>, current: Option<&'a [u8]>, } impl<'a> FakeStreamingIterator<'a> { fn new(inner: Box<StreamingIterator<Item = [u8]>>) -> FakeStreamingIterator<'a> { FakeStreamingIterator { inner: inner, current: None, } } } impl<'a> StreamingIterator for FakeStreamingIterator<'a> { type Item = [u8]; fn advance(&mut self) { self.current = self.inner.next(); } fn get(&self) -> Option<&[u8]> { self.current.map(|x| x) } }
我发现错误始终源于生命周期不匹配,对比两个示例的主要差异有两点:
- 前者持有具体类型的Box,而我的用例需要持有trait对象的Box
- 前者使用引用的引用,而我需要直接使用切片
我理解这里存在两个逻辑生命周期:迭代器自身的生命周期,以及当前切片的生命周期,且切片的生命周期应该短于迭代器的生命周期,但不知道怎么编写符合要求的代码。
内容的提问来源于stack exchange,提问作者stestagg
相关产品推荐
相关产品推荐

