为什么我不能 return 从字符串生成的 &str 值?
Why can't I return an &str value generated from a String?
我无法理解为什么我不能 return 从 String
生成的 &str
值(天哪,as_str
什么时候准备好了吗?)我做错了什么。我之所以有这个想法,是因为我所做的任何事情都无法使价值足够长的时间来使用。
我正在尝试为自定义结构实施 error::Error
:
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
}
}
(对于完整的片段,这里是 playpen)
我不知道如何从 description
中 return &str,我想重用 Display
逻辑,除非我完全误解了什么description
应该是 returning(也许是问题的简短描述)。或者,我遇到了与 format!(...)
的 return 相同的问题,这是一个我似乎无法活到对我有用的变量。
首先,让我们看看实际预期的寿命是多少。 description
:
的签名中有一个隐含的生命周期
fn description(&self) -> &str
// Can be rewritten as
fn description<'a>(&'a self) -> &'a str
returned 指针必须至少在 self
期间有效。现在考虑 s
。它将持有一个 String
,一个拥有的字符串,并且它在函数结束时超出范围。到return&s
就无效了,因为return函数的时候s
就没了。 trim
return 是借用 s
的字符串切片,但该切片再次仅在 s
有效期间有效。
您需要 return 一个比方法调用还长的字符串切片,因此这排除了堆栈上的任何内容。如果您可以自由选择 return 类型,解决方案是将字符串移出函数。为此,需要一个拥有的字符串,然后 return 类型将是 String
,而不是 &str
。遗憾的是,您无法在此处自由选择 return 类型。
要return一个比方法调用还长的字符串切片,我看到两个选项:
使用 &'static
字符串切片。这肯定会超过调用,但它需要在编译时知道该字符串。字符串文字的类型为 &'static str
。如果描述不包含任何动态数据,这是一个合适的选项。
将拥有的字符串存储在 LexicalError
本身中。这确保您可以 return 一个指向它的指针,该指针在 self
的整个生命周期内都有效。可以在LexicalError
中增加一个字段desc: String
,在构造错误的时候进行格式化。然后该方法将实现为
fn description(&self) -> &str {
&self.desc
}
为了重复使用,可以让Display
写入相同的字符串。
根据 documentation of Error
,Display
可用于提供更多详细信息。如果您希望在错误中包含动态数据,那么 Display
是格式化它的好地方,但您可以省略 description
。这将允许使用第一种方法。
我无法理解为什么我不能 return 从 String
生成的 &str
值(天哪,as_str
什么时候准备好了吗?)我做错了什么。我之所以有这个想法,是因为我所做的任何事情都无法使价值足够长的时间来使用。
我正在尝试为自定义结构实施 error::Error
:
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
}
}
(对于完整的片段,这里是 playpen)
我不知道如何从 description
中 return &str,我想重用 Display
逻辑,除非我完全误解了什么description
应该是 returning(也许是问题的简短描述)。或者,我遇到了与 format!(...)
的 return 相同的问题,这是一个我似乎无法活到对我有用的变量。
首先,让我们看看实际预期的寿命是多少。 description
:
fn description(&self) -> &str
// Can be rewritten as
fn description<'a>(&'a self) -> &'a str
returned 指针必须至少在 self
期间有效。现在考虑 s
。它将持有一个 String
,一个拥有的字符串,并且它在函数结束时超出范围。到return&s
就无效了,因为return函数的时候s
就没了。 trim
return 是借用 s
的字符串切片,但该切片再次仅在 s
有效期间有效。
您需要 return 一个比方法调用还长的字符串切片,因此这排除了堆栈上的任何内容。如果您可以自由选择 return 类型,解决方案是将字符串移出函数。为此,需要一个拥有的字符串,然后 return 类型将是 String
,而不是 &str
。遗憾的是,您无法在此处自由选择 return 类型。
要return一个比方法调用还长的字符串切片,我看到两个选项:
使用
&'static
字符串切片。这肯定会超过调用,但它需要在编译时知道该字符串。字符串文字的类型为&'static str
。如果描述不包含任何动态数据,这是一个合适的选项。将拥有的字符串存储在
LexicalError
本身中。这确保您可以 return 一个指向它的指针,该指针在self
的整个生命周期内都有效。可以在LexicalError
中增加一个字段desc: String
,在构造错误的时候进行格式化。然后该方法将实现为fn description(&self) -> &str { &self.desc }
为了重复使用,可以让
Display
写入相同的字符串。
根据 documentation of Error
,Display
可用于提供更多详细信息。如果您希望在错误中包含动态数据,那么 Display
是格式化它的好地方,但您可以省略 description
。这将允许使用第一种方法。