我很难理解为什么我不能返回一个从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
}
}
字符串
(for完整的片段,这里是playpen)
我不知道如何从description
返回一个&str,我想重用Display
逻辑,当然,除非我完全误解了description
应该返回什么(也许是问题的简短描述)。或者,我在返回format!(...)
时遇到了同样的问题,这是一个变量,我似乎不能活得足够长,对我有用。
2条答案
按热度按时间hvvq6cgz1#
首先,让我们看看实际上期望的生存期是什么。在
description
的签名中有一个隐式的生存期:字符串
返回的指针必须在至少与
self
一样长的时间内有效。现在考虑s
。它将保存一个String
,一个拥有的字符串,并且它在函数结束时超出了作用域。返回&s
将是无效的,因为当函数返回时s
已经消失了。trim
返回一个借用s
的字符串切片,但是该切片再次仅在s
的时间内有效。你需要返回一个在方法调用之后仍然存在的字符串切片,所以这排除了堆栈上的任何东西。如果你可以自由选择返回类型,一个解决方案是将字符串移出函数。为此,需要一个拥有的字符串,然后返回类型将是
String
,而不是&str
。不幸的是,你不能自由选择返回类型。要返回一个在方法调用之后仍然存在的字符串切片,我看到两个选项:
1.使用
&'static
字符串切片。这肯定会比调用更持久,但它要求字符串在编译时已知或泄漏内存。字符串字面量具有&'static str
类型。如果描述不包含任何动态数据,这是一个合适的选项。1.在
LexicalError
本身中存储一个拥有的字符串。这可以确保您可以返回一个指向它的指针,该指针在self
的整个生命周期内都有效。您可以向LexicalError
添加一个字段desc: String
,并在构造错误时进行格式化。然后该方法将实现为型
为了重用,可以让
Display
写相同的字符串。根据documentation of
Error
,Display
可以用来提供额外的细节。如果你想在错误中包含动态数据,那么Display
是一个格式化它的好地方,但是你可以在description
中省略它。这将允许使用第一种方法。qojgxg4l2#
你可以用Box::leak()从String中获取一个静态str,使用后,手动删除它。
字符串