rust 为什么我不能返回从String生成的&str值?

jdg4fx2g  于 2024-01-08  发布在  其他
关注(0)|答案(2)|浏览(130)

我很难理解为什么我不能返回一个从String生成的&str值(天哪,as_str什么时候才能准备好?),我做错了什么。我得到这个想法是因为我做的任何事情都没有使值存活足够长的时间。
我正在尝试为自定义结构体实现error::Error

  1. impl error::Error for LexicalError {
  2. fn description(&self) -> &str {
  3. let s = format!("{}", self);
  4. // s doesn't live long enough to do this, I've tried
  5. // cloning s and using that, but still the clone doesn't
  6. // live long enough.
  7. s.trim()
  8. }
  9. fn cause(&self) -> Option<&error::Error> {
  10. None
  11. }
  12. }

字符串
(for完整的片段,这里是playpen
我不知道如何从description返回一个&str,我想重用Display逻辑,当然,除非我完全误解了description应该返回什么(也许是问题的简短描述)。或者,我在返回format!(...)时遇到了同样的问题,这是一个变量,我似乎不能活得足够长,对我有用。

hvvq6cgz

hvvq6cgz1#

首先,让我们看看实际上期望的生存期是什么。在description的签名中有一个隐式的生存期:

  1. fn description(&self) -> &str
  2. // Can be rewritten as
  3. fn description<'a>(&'a self) -> &'a str

字符串
返回的指针必须在至少与self一样长的时间内有效。现在考虑s。它将保存一个String,一个拥有的字符串,并且它在函数结束时超出了作用域。返回&s将是无效的,因为当函数返回时s已经消失了。trim返回一个借用s的字符串切片,但是该切片再次仅在s的时间内有效。
你需要返回一个在方法调用之后仍然存在的字符串切片,所以这排除了堆栈上的任何东西。如果你可以自由选择返回类型,一个解决方案是将字符串移出函数。为此,需要一个拥有的字符串,然后返回类型将是String,而不是&str。不幸的是,你不能自由选择返回类型。
要返回一个在方法调用之后仍然存在的字符串切片,我看到两个选项:
1.使用&'static字符串切片。这肯定会比调用更持久,但它要求字符串在编译时已知或泄漏内存。字符串字面量具有&'static str类型。如果描述不包含任何动态数据,这是一个合适的选项。
1.在LexicalError本身中存储一个拥有的字符串。这可以确保您可以返回一个指向它的指针,该指针在self的整个生命周期内都有效。您可以向LexicalError添加一个字段desc: String,并在构造错误时进行格式化。然后该方法将实现为

  1. fn description(&self) -> &str {
  2. &self.desc
  3. }


为了重用,可以让Display写相同的字符串。
根据documentation of ErrorDisplay可以用来提供额外的细节。如果你想在错误中包含动态数据,那么Display是一个格式化它的好地方,但是你可以在description中省略它。这将允许使用第一种方法。

展开查看全部
qojgxg4l

qojgxg4l2#

你可以用Box::leak()从String中获取一个静态str,使用后,手动删除它。

  1. fn main() {
  2. let s1 = format!("abc");
  3. // s is static lifetime, can match the lifetime of &str
  4. let s = Box::leak(s1.into_boxed_str());
  5. // drop it manually.
  6. unsafe {
  7. mem::drop(Box::from_raw(s as *const str as *mut str));
  8. }
  9. }

字符串

相关问题