簡體   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