#How can I pass a reference to a mutated value within a loop?

1 messages · Page 1 of 1 (latest)

nova pebble
#

Hi, I'm working on a project and I've run into a problem.
I have a struct with two fields: a referenced Array<T> storing a reference to input, and another Array<T> that stores output.

struct RandomStruct<'a, T: HasAfEnum> {inputs: LazyCell<&'a Array<T>>, outputs: Array<T>}

It has a method implemented that modifies both fields and stores them in.

impl<'a, T: HasAfEnum> RandomStruct<'a, T> {
    pub fn modify_and_store_inputs_and_outputs(&mut self, x: &'a Array<T>) {
        self.inputs.fill(x).ok();
        self.outputs = x * x;
    }
} ```

After defining "a", "b", and "inputs", I want to borrow the outputs stored in "a" and store that reference in "b.inputs", (neither fields will be modified more then once per loop).  

```rust
fn main() {
    let mut a: RandomStruct<f32> = RandomStruct::default();
    let mut b: RandomStruct<f32> = RandomStruct::default();

    let inputs: Array<f32> = randn(dim4!(5, 5));

    for i in 0..100 {
        a.modify_and_store_inputs_and_outputs(&inputs);
        b.modify_and_store_inputs_and_outputs(&a.outputs);
    }
}

This however the compiler doesn't like, and I'm lost on how to resolve it.

safe jasper
#

by storing a reference to a inside of b (b.modify_and_store_inputs_and_outputs(&a.outputs)), you are making a unmodifiable as long as b exists.

#

Is your goal just to share data without copying it? Then you should store your Array<T> in Arcs rather than using & references.

nova pebble
#

I haven't used Arcs before, but that is indeed my goal, thx for the suggestion. Ill look into it.

nova pebble
#

So something like this?

struct RandomStruct<T: HasAfEnum> {pub inputs: LazyCell<Arc<Array<T>>>, pub outputs: Arc<Array<T>>}
impl<T: HasAfEnum> Default for RandomStruct<T> {
    fn default() -> Self { Self {inputs: LazyCell::new(), outputs: Arc::new(Array::new_empty(dim4!(1)))}}
}

impl<T: HasAfEnum> RandomStruct<T> {
    pub fn modify_and_store_inputs(&mut self, x: Arc<Array<T>>) {
        self.outputs = Arc::new(x.as_ref() * x.as_ref());
        self.inputs.fill(x).ok();
    }
}

fn main() {
    let mut a: RandomStruct<f32> = RandomStruct::default();
    let mut b: RandomStruct<f32> = RandomStruct::default();

    let inputs: Arc<Array<f32>> = Arc::new(randn(dim4!(5, 5)));

    for i in 0..100 {
        a.modify_and_store_inputs(Arc::clone(&inputs));
        b.modify_and_store_inputs(Arc::clone(&a.outputs));
    }
}