Rust - 内部带有所有者的 mut ref 的迭代器

Rust - iterator with mut ref of owner inside

我与迭代器斗争,迭代器也会改变它的所有者的其他字段。

我重新创建了一个简化示例 Playground:

#[derive(PartialEq)]
enum ResourceEnum {
    Food,
}

struct Resource {
    r#type: ResourceEnum,
    amount: u32,
}

trait Building {
    fn produce(&self) -> Option<Resource>;
}

struct Farm {}

struct City {
    buildings: Vec<Box<dyn Building>>,
    resources: Vec<Resource>,
}

impl City {
    fn add_resource(&mut self, received: Option<Resource>) {
        if let Some(received) = received {
            if let Some(mut res) = self
                .resources
                .iter_mut()
                .find(|r| r.r#type == received.r#type)
            {
                res.amount += received.amount;
            } else {
                self.resources.push(received);
            }
        }
    }
}

impl Building for Farm {
    fn produce(&self) -> Option<Resource> {
        Some(Resource {
            r#type: ResourceEnum::Food,
            amount: 10,
        })
    }
}

fn main() {
    let mut city = City {
        buildings: vec![],
        resources: vec![],
    };

    city.buildings.iter().for_each(|f| {
        city.add_resource(f.produce());
    });
}

错误:

error[E0502]: cannot borrow `city` as mutable because it is also borrowed as immutable
  --> src/main.rs:55:36
   |
53 |     city.buildings.iter().for_each(|f| {
   |     --------------        -------- ^^^ mutable borrow occurs here
   |     |                     |
   |     |                     immutable borrow later used by call
   |     immutable borrow occurs here
54 |         city.add_resource(f.produce());
   |         ---- second borrow occurs due to use of `city` in closure

我想要实现的目标是让一个结构体容纳我的 'world' -> 城市,它拥有农场等建筑物以及食物等所有可用资源。

在每次状态更新时,我想计算所有农场的收获等等...并将生产的资源添加到城市存储中,但如果不将所有生产存储为单独的 Vector 并迭代,我想不出办法它再次只是将它添加到城市存储中,这似乎是多余的。

我想我很难找到更好的方法来设计我的世界的结构,但想不出任何东西。

当然可以做的就是将资源的生产分开,加入到城市中。我修改了你的 Playground 以使其编译:

let mut v:Vec<Option<ResourceEnum>> = city.buildings.iter().map(|f| f.produce()).collect();
v.drain(..).for_each(|r| city.add_resource(r));

但肯定不能在迭代同一对象内的建筑物时调用 City 上的可变函数。