0

I'm new to Rust, attempting to port some code from python. I'd like to ask a trait for its collection of objects, do some filtering on it, and then pass the objects back to a method on the trait, making it pick and return one of the objects. The borrow checker is giving me an error due to attempting to borrow multiple times; cannot borrow *player as mutable when already borrowed as immutable.

Example:

use std::borrow::Borrow;

trait Player {
    fn items(&self) -> Vec<&Item>;
    fn items_mut(&mut self) -> Vec<&mut Item>;
    fn should_choose_item<I: Borrow<Item>>(&self, possible_items: &Vec<I>) -> bool;
    fn choose_item<'a>(&'a self, _possible_items: Vec<&'a mut Item>) -> &'a mut Item;
}

#[derive(Debug)]
struct Item {
    can_choose: bool,
    level: u8,
}

fn method<'a, P: Player>(player: &'a mut P) -> &'a mut Item {
    let mut possible_items = player.items();
    possible_items.retain(|dwarf| dwarf.can_choose);

    if player.should_choose_item(&possible_items) {
        let mut possible_items = player.items_mut();
        possible_items.retain(|i| i.can_choose);
        return player.choose_item(possible_items);
    }
    let mut possible_items = player.items_mut();
    possible_items.retain(|i| i.can_choose);
    possible_items.pop().unwrap()
}

Like I mentioned, I'm still learning rust, and so if there is a better architecture for doing this (getting some state from a trait object, processing it in some way, and then passing back to the trait), I'd be interested in hearing about it.

  • Are you sure you really want `Vec<&Item>` and `Vec<&mut Item>`? More likely you need `&Vec` ([or better, `&[Item]`](https://stackoverflow.com/questions/40006219/why-is-it-discouraged-to-accept-a-reference-string-vec-or-box-as-a-function)) and `&mut Vec`. Try to implement this trait and see if you succeed. – Chayim Friedman Aug 31 '23 at 16:08
  • Please post the full error from `cargo check` (not your IDE). – Chayim Friedman Aug 31 '23 at 16:10
  • Be aware that you can't have multiple `mut` references to the same item, or even a `mut` and a non-`mut` at the same time. That means, as long as you borrow `Vec<&mut>` from your struct, you **cannot** call `&self` methods on it, because those two references would alias. – Finomnis Sep 01 '23 at 05:48

0 Answers0