不清楚链接问题的重复
这个问题是关于返回对所拥有的struct的成员的引用,而不是关于在同一个对象上存储对拥有值的引用。
我希望得到一些解释,或者对特定情况下发生的事情提供一些提示。
我使用streaming iterators library构建运行时管道,其中在编译时不知道确切的迭代器类型。例如,我想构建一个像
这样的管道__dict__
为了有效地做到这一点,在迭代器中借用切片似乎很重要。我最好的尝试是创建一个迭代器,gzip解压缩由另一个迭代器传入的read a file > gunzip it > parse the contents > extract fields
in a playground。
产生的错误是:
[u8]
来自图书馆的an example:
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
类型。这是必需的,因为在编译时不知道父迭代器。在我看来,有两个合乎逻辑的生命周期:
切片寿命必须短于迭代器生存期。我假设有一种情况,Rust可以保证Box
没有被调用,而advance(&mut)
活着的结果是活跃的借用,但我是不知道如何写这个。
我已经阅读了很多关于借用和生命的内容,但不了解这种情况的不同。