Why can't I return an &str value generated from a String?
lifetime, rust
Solution
First, let’s take a look at what lifetime is actually expected. There is an implicit lifetime in the signature of `description`:
fn description(&self) -> &str
// Can be rewritten as
fn description<'a>(&'a self) -> &'a str
The returned pointer must be valid for at least as long as `self`. Now consider `s`. It will hold a `String`, an owned string, and it goes out of scope at the end of the function. It would be invalid to return `&s`, because `s` is gone when the function returns. `trim` returns a string slice that borrows `s`, but the slice is again only valid for as long as `s` is.
You need to return a string slice that outlives the method call, so this rules out anything on the stack. If you were free to choose the return type, a solution would be to move the string out of the function. For that an owned string would be required, and then the return type would be `String`, not `&str`. Unfortunately, you are not free to choose the return type here.
To return a string slice that outlives the method call, I see two options:
Use a `&'static` string slice. This will certainly outlive the call, but it requires that the string is known at compile time or to leak memory. String literals have type `&'static str`. This is a suitable option if the description does not contain any dynamic data.
Store an owned string in `LexicalError` itself. This ensures that you can return a pointer to it that is valid for the entire lifetime of `self`. You can add a field `desc: String` to `LexicalError` and do the formatting when the error is constructed. Then the method would be implemented as
fn description(&self) -> &str {
&self.desc
}
For re-use, you can make `Display` write the same string.
According to the documentation of `Error`, `Display` may be used to provide additional detail. If you wish to include dynamic data in the error, then `Display` is a great place to format it, but you can omit it for `description`. This would allow the first approach to be used.
Problem
I'm having some trouble trying to grasp why I can't return an `&str` value generated from a `String` (goodness, when will `as_str` be ready?) and I'm doing something wrong. I get this idea because nothing that I do makes the value live long enough to use. I'm trying to implement `error::Error` for a custom struct: ``` impl error::Error for LexicalError { fn description(&self) -> &str { let s = format!("{}", self); // s doesn't live long enough to do this, I've tried // cloning s and using that, but still the clone doesn't // live long enough. s.trim() } fn cause(&self) -> Option<&error::Error> { None } } ``` (for the complete snippet, here is the playpen) I can't figure out how to return an &str from `description`, I'd like to reuse the `Display` logic, unless of course I'm completely misunderstanding what `description` should be returning (perhaps the short description of the issue). Either, I get the same issue with the return of `format!(...)` which is a variable I can't seem to get to live long enough to be useful to me.