Shared object reference between different Rust containers without copy

Advertisements

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.

>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

Leave a ReplyCancel reply