为什么不能返回从字符串生成的& str值? [英] Why can't I return an &str value generated from a String?
问题描述
我在尝试理解为什么我不能返回从String
生成的&str
值时遇到麻烦(好的,as_str
什么时候准备好了?),我做错了什么.我之所以知道这个主意,是因为我所做的任何事情都无法使该价值存在足够长的时间以供使用.
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.
我正在尝试为自定义结构实现error::Error
:
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)
我不知道如何从description
返回& str,我想重用Display
逻辑,除非我完全完全误解了description
应该返回什么(也许问题的简短描述).要么,我得到与format!(...)
相同的问题,这是一个变量,我似乎无法生存很长时间以至于对我没有用.
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.
推荐答案
首先,让我们看一下实际预期的寿命. description
的签名中存在隐式生存期:
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
返回的指针的有效期至少应与self
一样长.现在考虑s
.它将包含一个String
(一个拥有的字符串),并且在函数末尾超出范围.返回&s
将是无效的,因为函数返回时s
消失了. trim
返回借用s
的字符串切片,但是该切片再次仅在s
有效的时间内有效.
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.
您需要返回一个超出方法调用寿命的字符串切片,因此这将排除堆栈中的所有内容.如果您可以自由选择返回类型,则解决方案是将字符串移出函数.为此,将需要一个拥有的字符串,然后返回类型将是String
,而不是&str
.不幸的是,您不能在这里自由选择返回类型.
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:
-
使用
&'static
字符串切片.这肯定会超出调用的寿命,但是它要求在编译时就知道该字符串.字符串文字的类型为&'static str
.如果说明中不包含任何动态数据,则这是一个合适的选项.
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.
将拥有的字符串存储在LexicalError
本身中.这样可以确保您可以返回指向self
整个生命周期内都有效的指针.您可以将字段desc: String
添加到LexicalError
并在构造错误时进行格式化.然后该方法将被实现为
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
}
要重新使用,可以使Display
写入相同的字符串.
For re-use, you can make Display
write the same string.
根据Error
的文档,Display
可用于提供其他细节.如果希望在错误中包括动态数据,那么Display
是格式化它的好地方,但是您可以为description
忽略它.这将允许使用第一种方法.
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.
这篇关于为什么不能返回从字符串生成的& str值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!