How can you create a list of objects that reference a shared property in the container object?

97 Views Asked by At

Commonly, a program object will contain a list of objects that reference a shared property in the container object.

Rust, without using a heap allocated reference counter or similar, prevents multiple owners to the same reference.

Example

The following code demonstrates an example pattern commonly encountered in the wild:

#[derive(Debug)]
struct Identity {
    token: String,
}

#[derive(Debug)]
struct Service<'a> {
    identity: &'a Identity,
    uri: String,
}

impl<'a> Service<'a> {
    pub fn new(identity: &'a Identity, uri: String) -> Self {
        Service { identity, uri }
    }
}

#[derive(Debug)]
struct Services<'a> {
    identity: Identity,
    services: Vec<Service<'a>>,
}

impl<'a> Services<'a> {
    pub fn new() -> Self {
        Services {
            identity: Identity {
                token: String::new(),
            },
            services: Vec::new(),
        }
    }

    pub fn add_service(&'a mut self, uri: String) {
        self.services.push(Service {
            identity: &self.identity,
            uri,
        });
    }
}

fn main() {
    let mut services = Services::new();
    services.add_service(String::from("https://api.stackexchange.com"));
    services.add_service(String::from("https://api.stackoverflow.com"));
    println!("{:?}", services);
}

Output

error[E0499]: cannot borrow `services` as mutable more than once at a time
  --> src/main.rs:45:5
   |
44 |     services.add_service(String::from("https://api.stackexchange.com"));
   |     -------- first mutable borrow occurs here
45 |     services.add_service(String::from("https://api.stackoverflow.com"));
   |     ^^^^^^^^
   |     |
   |     second mutable borrow occurs here
   |     first borrow later used here

error[E0502]: cannot borrow `services` as immutable because it is also borrowed as mutable
  --> src/main.rs:46:22
   |
44 |     services.add_service(String::from("https://api.stackexchange.com"));
   |     -------- mutable borrow occurs here
45 |     services.add_service(String::from("https://api.stackoverflow.com"));
46 |     println!("{:?}", services);
   |                      ^^^^^^^^
   |                      |
   |                      immutable borrow occurs here
   |                      mutable borrow later used here

Question

How can you create this pattern in Rust with the expectation that the Services vector will be updated within a GUI REPL loop?

0

There are 0 best solutions below