![](/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.