Ask Lifetime - borrowed value does not live long enough [solved]

I have struck like this, which is working fine

pub struct Head<'s> {
    title: Option<String>,
    css: Vec<&'s str>
}
impl<'s> Head<'s> {
    ....
    pub fn add_css(&mut self, css: &'s str) {
        self.css.push(css);
    }
    ....
}

But it wont compile when I tried to format the str

pub fn add_css(&mut self, css: &'s str) {
    self.css.push(
        format!("<link rel='stylesheet' href='{}' />", css).as_str()
    );
}

am I missing something?

The format! makes a String, but if you don't assign that anywhere, then it will be dropped at the end of its expression. The as_str() is trying to borrow a str from the String, so it can't live any longer than the thing it's borrowing from. Your Vec<&'s str> wants all strings pushed to it to last at least for the lifetime 's.

If you change to Vec<String>, it can own everything. You could also try Cow<'s, str> -- then the original example could use push(Cow::Borrowed(css)), and the latter push(Cow::Owned(format!(...))).

TL;DR - someone needs to own the string you've formatted.

2 Likes

That was so cool