繁体   English   中英

如何将可变引用传递给 Rust 中迭代器循环内的函数?

[英]How can I pass my mutable references to a function inside iterator loops in Rust?

我有以下代码:

    pub fn run_systems(mut self) {
        for mut agent in self.agents.iter_mut() {
            for mut system_id in agent.systems.iter_mut() {
                let system = self.systems.get(system_id).unwrap();
                system.simulate(&mut agent,  &mut self);
            }
        }
    }

我在system.simulate行上收到以下错误:

cannot borrow `agent` as mutable more than once at a time
second mutable borrow occurs here`. Apparently, iterating over the arrays is a borrowing operation.

我也试过不使用iter函数并直接对拥有的值进行迭代(不确定那是什么):

    pub fn run_systems(mut self) {
        for mut agent in self.agents {
            for mut system_id in agent.systems {
                let system = self.systems.get(&system_id).unwrap();
                system.simulate(&mut agent,  &mut self);
            }
        }
    }

但是一旦我引用&system_id ,它就会for mut system_id in agent.systems {行中的for mut system_id in agent.systems {检测到隐式借用

borrow of partially moved value: `agent`
partial move occurs because `agent.systems` has type `Vec<String>`, which does not implement the `Copy` traitrustcE0382
lib.rs(72, 34): `agent.systems` partially moved due to this implicit call to `.into_iter()`
collect.rs(233, 18): this function takes ownership of the receiver `self`, which moves `agent.systems`

我尝试了各种方法来编写此代码,但找不到有效的方法。 如何迭代这些值,同时还能够将对其内容的可变引用传递给其他函数?

是它游乐场

use std::collections::HashMap;

struct World {
    agents: Vec<Agent>,
    systems: HashMap<String, Box<dyn System>>,
}
impl World {
    pub fn new() -> World {
        return World {
            agents: Vec::new(),
            systems: HashMap::new(),
        };
    }
    pub fn run_systems(mut self) {
        for mut agent in self.agents {
            for system_id in agent.systems {
                let system = self.systems.get(&system_id).unwrap();
                system.simulate(&mut agent, &mut self);
            }
        }
    }
    /// Adds an agent to the world
    pub fn add_agent(&mut self, agent: Agent) -> &Self {
        self.agents.push(agent);
        return self;
    }

    /// Adds a system to the available systems
    pub fn add_system<S: System + 'static>(&mut self, system: S, id: String) -> &Self {
        self.systems.insert(id, Box::new(system));
        return self;
    }
}

struct Agent {
    systems: Vec<String>,
}

trait System {
    fn simulate(&self, agent: &mut Agent, world: &mut World);
}

#[derive(Default)]
struct SomeSystem;
impl System for SomeSystem {
    fn simulate(&self, agent: &mut Agent, world: &mut World) {
        // Code here
    }
}

fn main() {
    let system_id = String::from("SOME_SYSTEM");
    let world = World::new();
    world.add_system(SomeSystem::default(), system_id);
    let agent = Agent {
        systems: vec![system_id],
    };
    world.add_agent(agent);
    world.run_systems();
}
error[E0382]: borrow of partially moved value: `agent`
   --> src/main.rs:18:33
    |
16  |             for system_id in agent.systems {
    |                              -------------
    |                              |
    |                              `agent.systems` partially moved due to this implicit call to `.into_iter()`
    |                              help: consider borrowing to avoid moving into the for loop: `&agent.systems`
17  |                 let system = self.systems.get(&system_id).unwrap();
18  |                 system.simulate(&mut agent, &mut self);
    |                                 ^^^^^^^^^^ value borrowed here after partial move
    |
note: this function takes ownership of the receiver `self`, which moves `agent.systems`
    = note: partial move occurs because `agent.systems` has type `Vec<String>`, which does not implement the `Copy` trait

error[E0502]: cannot borrow `self` as mutable because it is also borrowed as immutable
  --> src/main.rs:18:45
   |
17 |                 let system = self.systems.get(&system_id).unwrap();
   |                              ------------ immutable borrow occurs here
18 |                 system.simulate(&mut agent, &mut self);
   |                        --------             ^^^^^^^^^ mutable borrow occurs here
   |                        |
   |                        immutable borrow later used by call

error[E0382]: borrow of partially moved value: `self`
  --> src/main.rs:18:45
   |
15 |         for mut agent in self.agents {
   |                          -----------
   |                          |
   |                          `self.agents` partially moved due to this implicit call to `.into_iter()`
   |                          help: consider borrowing to avoid moving into the for loop: `&self.agents`
...
18 |                 system.simulate(&mut agent, &mut self);
   |                                             ^^^^^^^^^ value borrowed here after partial move
   |
   = note: partial move occurs because `self.agents` has type `Vec<Agent>`, which does not implement the `Copy` trait

error[E0596]: cannot borrow `world` as mutable, as it is not declared as mutable
  --> src/main.rs:54:5
   |
53 |     let world = World::new();
   |         ----- help: consider changing this to be mutable: `mut world`
54 |     world.add_system(SomeSystem::default(), system_id);
   |     ^^^^^ cannot borrow as mutable

error[E0382]: use of moved value: `system_id`
  --> src/main.rs:56:23
   |
52 |     let system_id = String::from("SOME_SYSTEM");
   |         --------- move occurs because `system_id` has type `String`, which does not implement the `Copy` trait
53 |     let world = World::new();
54 |     world.add_system(SomeSystem::default(), system_id);
   |                                             --------- value moved here
55 |     let agent = Agent {
56 |         systems: vec![system_id],
   |                       ^^^^^^^^^ value used here after move

error[E0596]: cannot borrow `world` as mutable, as it is not declared as mutable
  --> src/main.rs:58:5
   |
53 |     let world = World::new();
   |         ----- help: consider changing this to be mutable: `mut world`
...
58 |     world.add_agent(agent);
   |     ^^^^^ cannot borrow as mutable

在任何一种情况下,这都不能与定义simulate()的方式一起使用。 它需要一个&mut Self作为第二个参数,这意味着对self独占访问 - 所有self 但这是不可能的,因为 A) 在第一种情况下通过迭代器引用self或 B) 在第二种情况下通过取得self.agents所有权, self已部分解构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM