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