Struct member lifetimes

I'm developing my real first project in Rust and I stumbled upon lifetimes.
Here's the code to describe my scenario:

struct A<'a> {
    ref_to_something: &'a String
}

impl<'a> A<'a> {
    pub fn new(s: &'a String) -> anyhow::Result<A> {
        Ok(A {
            ref_to_something: s
        })
    }
}

struct B<'a> {
    something: String,
    list_of_a: Vec<A<'a>>,
}

impl<'a> B<'a> {
    pub fn new() -> B<'a> {
        B {
            something: "hello".into(),
            list_of_a: vec![],
        }
    }

    pub fn add(&mut self) {
        if let Ok(a) = A::new(&self.something) {
            self.list_of_a.push(a);
        }
    }
}

The choice of String is arbitrary, it can be any type (in my case it was a struct). A needs a reference to something in order to be initialized and that something is specifically a member of B. On the other hand, B has a list of As. To add to the list, I need to pass the reference to my something which resides in B.

But for the function B::add Rust is telling me that I need to specify the lifetime of self, because there's a chance that self doesn't live long enough. Since I had this error I took a different approach to the problem (I'm not referencing that something in A anymore), but I wonder if I could have achieved what I wanted using the references as shown above or it simply a bad design choice on my part.

Your B struct is self-referential, which means that one field holds a reference to another. Such structs are not allowed in safe Rust. You will have to do something else.

How about not using a reference, and just storing the string directly?

2 Likes

Besides self-referentiality in particular, it is generally unwise to use references to build data structures. References are best at providing temporary access to something else that already exists; data structures should own (not reference) their contents. (There are exceptions — this is suggesting a strict distinction that doesn't actually exist — but this is a good heuristic to start with as a beginner.)

Can you say more about what your actual use case is, so we can suggest a better data structure?

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.