如何在 Rust 中迭代时调用方法

How to call a method while iterating in Rust

很抱歉,如果这很简单。我正在学习 Rust 并习惯了奇怪的借用系统。通常,您只需更改方法调用的语法即可获得所需的行为,但是,在这种情况下,现在似乎有办法了。

我的代码的简化版本是这样的:EventPump 如果来自 SDL。

struct Example {
    pump: EventPump
}

impl Example {
    fn method(&mut self) {
        for event in pump.poll_iter() {
            self.other_method();
        }
    }

    fn other_method(&self) {

    }
}

但是,我收到以下错误:

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
  --> src\game.rs:53:67
   |
30 |             for event in self.pump.poll_iter();
   |                          ---------------------
   |                          | 
   |                          mutable borrow occurs here
   |                          mutable borrow later used here
...
53 |                  self.other_method();
   |                  ^^^^ immutable borrow occurs here

可能有一些正确的方法可以做到这一点,这样我的结构就可以保持自己的所有权,但我还没有找到它。

我尝试了以下方法:

我也许可以将 iterable 的全部内容复制到一个 vector 之类的东西中,但这会破坏迭代器的目的,如果迭代器不是有限的怎么办?一定有更好的方法吧...

如果有更多 Rust 经验的人可以帮助我,我将不胜感激。

如果在同一块中存在结构的不可变引用时,如果您希望结构的属性可变,则需要 RefCell. This is called interior mutability.

如果需要 struct Exampleinterior mutability,那么您将需要 RefCell

use sdl2::{EventPump};

struct Example {
    pump: RefCell<EventPump> // wrap in RefCell
}

impl Example {
    // you have to decide whether you want a mutable or immutable chained methods
    // i.e. method and other_method should be of same mutability because
    // other method is called in method
    fn method(&self) {
        // borrow a mutable reference of pump inside a method with immutable self 
        let mut pump = self.pump.borrow_mut();
        for event in pump.poll_iter() {
            self.other_method();
        }
    }

    fn other_method(&self) {

    }
}

如果你有这样的模式:

fn method(&mut self) {
    for item in self.some_iterator_that_borrow_mut() {
        self.other_method();
    }
}

声明 恰好一个可变引用 的借用规则已被破坏: self.

有一个可变引用和一个不可变引用

为避免双重引用问题使用迭代器并将项目收集到 临时集合,例如 Vec:

impl Example {
    fn method(&mut self) {
        for event in self.pump.poll_iter().collect::<Vec<_>>(); {
            self.other_method();
        }
    }

    fn other_method(&self) {}
}