Borrow-checking for sub-structs

Hi,

Running into an issue of how to cleanly implement an aspect of my program. I have a top level container struct, which contains two vectors of structs, the first with traits TraitA and the second with traits TraitB. Each takes the form of Vec<Box<dyn TraitX>> respectively.

Currently implemented as so:

use std::usize;

struct Container {
    a: Vec<Box<dyn TraitA>>,
    b: Vec<Box<dyn TraitB>>
}
struct A {}

trait TraitA{
    fn method(&mut self, trait_B_vec: &Vec<Box<dyn TraitB>>);
}

impl TraitA for A{
    fn method(&mut self, trait_B_vec: &Vec<Box<dyn TraitB>>) {
        ; // Some effect
    }
}

// Struct B

struct B {}

trait TraitB{}

impl TraitB for B {}

Example structs for each trait are provided but in the actual code there are many.

There is a primary loop done by the container struct, which passes the vector of TraitB to each element of the TraitA vector, which calculates contributions of all parts b on each element of a. Currently implemented like so:

impl Container{
    fn get_A(&mut self, id: usize) -> &mut Box<dyn TraitA> {
        &mut self.a[id]
    }

    fn primary_loop(&mut self) {
        for i in 0..self.a.len() {
            self.get_A(i).method(&self.b);
        }
    }
}

I can't remove b from Container as Container has a number of hyperparameters. I know this is somewhat of a classic borrow checker question, but any suggestions for how to implement this so as not to bury everything under a load of RefCell<>s? Structs in b do not need to be mutable and can be read only, but structs in a must be as the purpose of the primary loop is to modify each element of a in turn.

Don't use getters.

    fn primary_loop(&mut self) {
        for ta in &mut self.a {
            ta.method(&self.b);
        }
    }

Other options include having some "view struct" or method that returns, say, (&mut [Box<dyn TraitA>], &[Box<dyn TraitB>]). Here's an article about the general scenario.

1 Like

That completely fixed my entire issue, thank you.

1 Like