![](/img/trans.png)
[英]How can I create my own data structure with an iterator that returns mutable references?
[英]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.