0

I am trying to store an object into 2 different reference vectors, and if I modify the object from first vector ref, it should be visible from the second vector.

I still haven't understood well borrowing so that's what I'm trying to acheive :

use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;
use std::vec::Vec;

struct A {
    x: u32,
}

impl Display for A {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.x)
    }
}

fn main() {
    let mut a = A{x: 1};

    let mut v1: Vec<&mut A> = Vec::new();
    let mut v2: Vec<&mut A> = Vec::new();

    v1.push(&mut a);
    v2.push(&mut a);

    let f: &mut A = v1[0];
    f.x = 3;

    for v in &v1 {
        println!("Value: {}", v);
    }

    for v in &v2 {
        println!("Value: {}", v);
    }
}

Of course this doesn't compile. What should I do to be able to store same object in different collection like objects ? (I don't see any concurency issue or borrowing here).

sigz
  • 89
  • 1
  • 8
  • 4
    Does this answer your question? [How to store a reference in a Vec in rust and use this later on in Rust?](https://stackoverflow.com/questions/63404153/how-to-store-a-reference-in-a-vec-in-rust-and-use-this-later-on-in-rust) – trent Sep 25 '20 at 13:34
  • 3
    [Here's how you might translate your code to use `RefCell`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=86b3e540aa758e2ab2ff207075a1036e). – trent Sep 25 '20 at 13:35
  • 1
    Also relevant: [How to represent shared mutable state?](/q/28418584/3650362) – trent Sep 25 '20 at 13:38
  • 2
    "I don't see any concurency issue or borrowing here" shared mutability is an issue in more contexts than "concurrency issues" e.g. iterator invalidation, and the compiler is not infinitely smart so *will* reject code which would technically work. For instance code which tries to create two mutable references to the same thing is simply not allowed even if it would be fine in the specific case being observed. – Masklinn Sep 25 '20 at 13:41
  • Thank you I really thought something was possible without Refcells, but seems that the best solution for me. – sigz Sep 25 '20 at 14:05
  • 2
    However, this is *not* one of those cases where the compiler is being excessively cautious by rejecting code that is actually sound; the semantics of `&mut` allow rearranging of loads and stores under the assumption that `v1[0]` and `v2[0]` do not alias, so this code would have undefined behavior even if you used `unsafe` to make it compile. If the `&mut` references were changed to `*mut` raw pointers, it might be made sound (raw pointers, like C pointers, have no aliasing guarantees). – trent Sep 25 '20 at 14:08
  • Maybe using pointers is the way to go for the OP. @sigz how important is it that you don't use `RefCell`? Can you use `unsafe`? – user4815162342 Sep 25 '20 at 18:47

0 Answers0