vec 中可变大小切片上的非消耗可变迭代器

问题描述

我有一个包含坐标 vec 的结构 (Lines)。 我正在尝试将非重叠子切片上的非消耗可变迭代器实现为 &mut [Coordinate]。每个子切片将代表存储在 Lines 中的 1 行。 -edit:此外,可以在不移动顶点的情况下重新排序索引列表。因此,不能假设顶点中的线与索引的顺序相同。

该实现适用于不可变迭代器(与下面的实现相同,但没有 muts)

https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=dc03530c82e8113ea532e5345dda4142

use std::ops::{Index,IndexMut};

#[derive(Debug)]
pub struct Coordinate {
    x: u32,y: u32,}

/// SOA containing multiple line geometries
/// All coordinates of all the lines are stored contiguously in vertices
/// start_indices & end_indices both contain 1 entry for every geometry
#[derive(Debug)]
struct Lines {
    vertices: Vec<Coordinate>,start_indices: Vec<usize>,end_indices: Vec<usize>,}
impl Lines {
    pub fn len(&self) -> usize {
        self.start_indices.len()
    }
    fn iter_mut(&mut self) -> LinesIterMut {
        LinesIterMut {
            lines: self,next_index: 0,}
    }
}

impl Index<usize> for Lines {
    type Output = [Coordinate];

    fn index(&self,index: usize) -> &Self::Output {
        &self.vertices[self.start_indices[index]..self.end_indices[index]]
    }
}
impl IndexMut<usize> for Lines {
    fn index_mut(&mut self,index: usize) -> &mut Self::Output {
        &mut self.vertices[self.start_indices[index]..self.end_indices[index]]
    }
}

pub struct LinesIterMut<'a> {
    lines: &'a mut Lines,next_index: usize,}
impl<'a> Iterator for LinesIterMut<'a> {
    type Item = &'a mut [Coordinate];

    fn next(&mut self) -> Option<Self::Item> {
        if self.next_index < self.lines.len() {
            let current_index = self.next_index;
            self.next_index += 1;
            Some(&mut self.lines[current_index])
        } else {
            None
        }
    }
}

fn main() {
    let mut my_lines = Lines {
        vertices: vec![
            Coordinate {
                x: 1,y: 2,},Coordinate {
                x: 4,y: 5,],start_indices: vec![0],end_indices: vec![2],};

    for line in my_lines.iter_mut() {
        line[0].y = 33;
        println!("=> {:?}",line);
    }
}

我收到以下生命周期错误

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/main.rs:54:23
   |
54 |             Some(&mut self.lines[current_index])
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: first,the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 50:5...
  --> src/main.rs:50:5
   |
50 |     fn next(&mut self) -> Option<Self::Item> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:54:23
   |
54 |             Some(&mut self.lines[current_index])
   |                       ^^^^^^^^^^
note: but,the lifetime must be valid for the lifetime `'a` as defined on the impl at 47:6...
  --> src/main.rs:47:6
   |
47 | impl<'a> Iterator for LinesIterMut<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/main.rs:50:46
   |
50 |       fn next(&mut self) -> Option<Self::Item> {
   |  ______________________________________________^
51 | |         if self.next_index < self.lines.len() {
52 | |             let current_index = self.next_index;
53 | |             self.next_index += 1;
...  |
57 | |         }
58 | |     }
   | |_____^
   = note: expected `Iterator`
              found `Iterator`

如何告诉编译器引用的生命周期与 Lines 相关?

-edit:使用@kmdreko 提供的链接https://stackoverflow.com/a/60072822/13138916 我写了这个。 它有效,但这安全吗?我怎么知道?

pub struct LinesIterMut<'a> {
    lines: &'a mut Lines,}
impl<'a> Iterator for LinesIterMut<'a> {
    type Item = &'a mut [Coordinate];

    fn next(&mut self) -> Option<Self::Item> {
        if self.next_index < self.lines.len() {
            let current_index = self.next_index;
            self.next_index += 1;
            Some(unsafe { std::mem::transmute(&mut self.lines[current_index]) }) // <<--- Only changed this line
        } else {
            None
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)