从迭代器返回切片时无法推断出适当的生命周期

时间:2017-10-02 16:01:49

标签: rust

我有一个简单的Vec<Point> struct Point {x: f32, y: f32, z: f32}。我的矢量代表3D中数十万行(事实上它可能是Vec<Vec<Point>>),因此我会跟踪所有行的开始/结束。

pub struct Streamlines {
    lengths: Vec<usize>,
    offsets: Vec<usize>,  // cumulative sum of lengths
    data: Vec<Point>,
}

我想为它创建一个非消费迭代器,可用如:

for streamline in &streamlines {
    for point in &streamline {
        println!("{} {} {}", point.x, point.y, point.z);
    }
    println!("")
}

我找到How to implement Iterator and IntoIterator for a simple struct?并开始使用copyi-err,改编:)

impl IntoIterator for Streamlines {
    type Item = &[Point];
    type IntoIter = StreamlinesIterator;

    fn into_iter(self) -> Self::IntoIter {
        StreamlinesIterator {
            streamlines: self,
            it_idx: 0
        }
    }
}

struct StreamlinesIterator {
    streamlines: &Streamlines,
    it_idx: usize
}

impl Iterator for StreamlinesIterator {
    type Item = &[Point];

    fn next(&mut self) -> Option<&[Point]> {
        if self.it_idx < self.streamlines.lengths.len() {
            let start = self.streamlines.offsets[self.it_idx];
            self.it_idx += 1;
            let end = self.streamlines.offsets[self.it_idx];

            Some(self.streamlines.data[start..end])
        }
        else {
            None
        }
    }
}

我使用了切片,因为我只想返回向量的一部分,然后我添加了生命周期,因为它是必需的,但现在我有这个错误cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements

事实上,我实际上并不知道我该对该死的<'a>做了什么。

1 个答案:

答案 0 :(得分:6)

  由于需求冲突,

无法推断泛型参数中的生命周期参数的适当生命期

那是因为你没有正确实现Iterator并且有类似的东西:

impl<'a> Iterator for StreamlinesIterator<'a> {
    type Item = &'a [Point];

    fn next(&mut self) -> Option<&[Point]> { /* ... */ }

    // ...
}

由于终身推断,这相当于:

impl<'a> Iterator for StreamlinesIterator<'a> {
    type Item = &'a [Point];

    fn next<'b>(&'b mut self) -> Option<&'b [Point]> { /* ... */ }

    // ...
}

这是尝试返回与迭代器which you cannot do一样长的引用。

如果您正确实施Iterator,则可行:

impl<'a> Iterator for StreamlinesIterator<'a> {
    type Item = &'a [Point];

    fn next(&mut self) -> Option<&'a [Point]> { /* ... */ }

    // Even better:   
    fn next(&mut self) -> Option<Self::Item> { /* ... */ }

    // ...
}
  

我实际上并不知道我该怎么做该死的<'a>

您应该返回并重新阅读The Rust Programming Language, second edition。如果您有特定的问题,Stack Overflow,IRC,用户论坛都将等待。