我在试图理解为什么我不能回来时遇到了一些麻烦 &str
从a生成的值 String
(天哪,什么时候会 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
}
}
(对于完整的片段,这里是 围栏)
我无法弄清楚如何返回&str description
,我想重复使用 Display
逻辑,除非我完全误解了什么 description
应该回来(也许是问题的简短描述)。要么,我得到了与返回相同的问题 format!(...)
这是一个变量,我似乎无法活得足够长,对我有用。
首先,让我们来看看实际预期的寿命。签名中有一个隐含的生命周期 description
:
fn description(&self) -> &str
// Can be rewritten as
fn description<'a>(&'a self) -> &'a str
返回的指针必须至少有效 self
。现在考虑 s
。它将持有一个 String
,一个拥有的字符串,它在函数末尾超出范围。返回将无效 &s
因为 s
函数返回时消失了。 trim
返回借用的字符串切片 s
,但切片只能再次有效 s
是。
您需要返回一个比方法调用更长的字符串切片,因此这将排除堆栈上的任何内容。如果您可以自由选择返回类型,解决方案是将字符串移出函数。为此,需要一个拥有的字符串,然后返回类型 String
不是 &str
。不幸的是,您无法在此自由选择返回类型。
要返回一个比方法调用更长的字符串切片,我看到两个选项:
用一个 &'static
字符串切片。这肯定比调用更长,但它要求在编译时知道字符串。字符串文字有类型 &'static str
。如果描述不包含任何动态数据,则这是一个合适的选项。
存储一个拥有的字符串 LexicalError
本身。这可以确保您可以返回指向它的指针,该指针在整个生命周期内都有效 self
。您可以添加字段 desc: String
至 LexicalError
并在构造错误时进行格式化。然后该方法将实现为
fn description(&self) -> &str {
&self.desc
}
如需重复使用,您可以制作 Display
写相同的字符串。
根据 的文件 Error
, Display
可用于提供其他细节。如果您希望在错误中包含动态数据,那么 Display
是一个很好的格式化的地方,但你可以省略它 description
。这将允许使用第一种方法。