使用 Itertools 的tuple_windows可变迭代器。



我试图在Vec中存储一系列条目。稍后,我需要通过Vec重新处理,在每个条目中填写关于下一个条目的一些信息。最小的例子是这样的:

struct Entry {
curr: i32,
next: Option<i32>
}
struct History {
entries: Vec<Entry>
}

,其中我想将next字段填充到下一个条目的curr值。为了实现这一点,我想在可变迭代器上使用Itertools中的tuple_windows函数。我希望我可以这样写一个函数:

impl History {    
fn fill_next_with_itertools(&mut self) {
for (a, b) in self.entries.iter_mut().tuple_windows() {
a.next = Some(b.curr);
}
}
}

(游乐场)

但是,它拒绝编译,因为迭代器Item的类型&mut Entry不是tuple_windows函数所要求的Clone。我知道有一种方法可以使用像这样的索引来迭代列表:

fn fill_next_with_index(&mut self) {
for i in 0..(self.entries.len()-1) {
self.entries[i].next = Some(self.entries[i+1].curr);
}
}

(游乐场)

但是我觉得itertools的方法更自然和优雅。达到同样效果的最好方法是什么?

来自文档:
tuple_window克隆迭代器元素,使它们可以成为连续窗口的一部分,这使得它最适合用于引用和其他值的迭代器,这些值的复制成本很低。

这意味着如果你要用&mut项来实现它,那么你就会有多个对同一事物的可变引用,这是未定义的行为。

如果你仍然需要共享的,可变的访问,你必须把它包装在Rc<RefCell<T>>,Arc<Mutex<T>>或类似的东西:

fn fill_next_with_itertools(&mut self) {
for (a, b) in self.entries.iter_mut().map(RefCell::new).map(Rc::new).tuple_windows() {
a.borrow_mut().next = Some(b.borrow().curr);
}
}

相关内容

  • 没有找到相关文章

最新更新