0

I have abstracted my problem inside the following code:

struct List<'a> {
    attr: &'a String
}

impl<'a> List<'a> {
    fn new() -> List<'a> {
        let my_attr = "Something";
        List {
            attr: &my_attr.to_string()
        }
    }
}

fn main() {
    List::new();
}

It yields some notices and fails compiling claiming that the borrowed value (my_attr) doesn't live long enough.

It makes sense, so for instance the following does indeed compile:

struct List<'a> {
    attr: &'a String
}

impl<'a> List<'a> {
    fn new(my_attr: &'a String) -> List<'a> {
        List {
            attr: my_attr
        }
    }
}

fn main() {
    let my_attr = "Something".to_string();
    List::new(&my_attr);
}

However, I like the first form more, especially from an encapsulation stand point.

Is it possible to create and also assign a reference to a value from within the new method (as per the failing example)?

1 Answer 1

2

The issue here is that a &'a String is a borrowed value - that is, it is a reference to a value that is stored elsewhere. On your first example, that "elsewhere" is the new function stack, and on the second it's main's stack.

You don't get an error on the second case because main's lifetime is bigger than your List's lifetime - that is, the List will die before main finishes. That is not the case of your first scenario, where the List is returned by new, and thus the reference is invalid.

The solution here is to make List own its String, instead of just taking a reference to it. This way, List's lifetime isn't linked to anything else.

struct List {
    attr: String,
}

impl List {
    fn new() -> List {
        let my_attr = "Something";

        List {
            attr: my_attr.to_string()
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

The code is just an abstraction, String is actually a File handler in my original code. I really want to use &String.
Why do you want to use a reference? Is your File shared between multiple structs?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.