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.
Amazon.com doesn't accept returns for items fulfilled by third-party sellers. The seller determines the return policy. You can see specific information per item in Your Orders. If the item you purchased from Amazon.com is returnable, you'll see a message saying so when you select Return or Replace Item in Your Orders.
The Return/Refund button will be greyed out for the time being. You can check your parcel's expected delivery date at the top of your Order Details page. The Return/Refund option will be made available when: Expected delivery date has passed, but you have yet to receive your parcel.
If you don't have a receipt, try to make the return within 30 days and the company may be able to find your purchase in its system if you used a debit or credit card for the transaction.
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 be known at compile time. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With