Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Shared object reference between different Rust containers without copy

I want to have multiple data containers for the same object with the same reference (pointer), and can’t figure out how to achieve that in Rust. Go can simply use reference to the object as below:

type container struct {
    id     int
    status string
}

m1 := make(map[int]*container)
m2 := make(map[int]*container)

c := &container{id: 1, status: "test"}
m1[1] = c
m2[1] = c

c.status = "changed"

fmt.Println(m1[1]) // &{1 changed}
fmt.Println(m2[1]) // &{1 changed}

I tried to use Box to allocate it in heap but cannot compile…

use std::{cell::Cell, collections::HashMap};

fn main() {
    let mut m1: HashMap<i32, Box<Container>> = HashMap::new();
    let mut m2: HashMap<i32, Box<Container>> = HashMap::new();

    let mut c = Box::new(Container {
        id: 1,
        status: Cell::new(String::from("test")),
    });
    m1.insert(1, c);
    m2.insert(1, c);
    c.status.set("changed".to_string());
}

struct Container {
    id: i32,
    status: Cell<String>,
}

I used Cell to allow interior mutability but not relevant to this question… I want to learn how to create this Container object once, and allocate it on heap, and share the object across different data containers.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Instead of Box, you need to use Rc or Arc depending on your sync needs:

use std::rc::Rc;
use std::{cell::Cell, collections::HashMap};

fn main() {
    let mut m1: HashMap<i32, Rc<Container>> = HashMap::new();
    let mut m2: HashMap<i32, Rc<Container>> = HashMap::new();

    let c = Rc::new(Container {
        id: 1,
        status: Cell::new(String::from("test")),
    });
    m1.insert(1, Rc::clone(&c));
    m2.insert(1, Rc::clone(&c));
    c.status.set("changed".to_string());
}

struct Container {
    id: i32,
    status: Cell<String>,
}

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading