【问题标题】:"borrowed value does not live long enough" when using `as_slice` [duplicate]使用`as_slice`时“借来的价值不够长” [重复]
【发布时间】:2014-09-24 00:37:09
【问题描述】:

我一直遇到这个问题,我不太明白为什么不能编译这个:

fn foo(bar: &'static str) -> Foo {
  let caps_off = bar.to_ascii_lower().as_slice();
  ...
}

错误:borrowed value does not live long enough

我有点理解这里的错误,但我不知道任何其他方法可以实现这一点。

我正在尝试将我的str 转换为小写,然后将其转换回str 类型。看起来很简单。

我在这里做错了什么以及如何解决它?

完整代码:

use std::collections::HashMap;
use std::ascii::StrAsciiExt;

struct Foo;

fn foo(bar: &'static str) -> Foo {
  let caps_off_ = bar.to_ascii_lower();
  let caps_off = caps_off_.as_slice();

  let mut my_foos:HashMap<&'static str, Foo> = HashMap::new();
  my_foos.insert("hi", Foo);
  *my_foos.find(&caps_off).clone().unwrap()
}

【问题讨论】:

    标签: rust


    【解决方案1】:

    由于编译器推断的信息,该错误很难理解。

    caps_off 的类型是什么?您没有指定它,因此编译器必须从其用法中推断出它。在这个表达式中只使用一次

    *my_foos.find(&caps_off).clone().unwrap()
    

    Map trait 上的find method 指定参数的类型为&amp;K。您将地图定义为HashMap&lt;&amp;'static str, Foo&gt;,因此K&amp;'static str。因此,参数的具体类型为&amp;&amp;'static str。参数是&amp;caps_off,因此您正在构建一个参考。编译器推断caps_off 必须是&amp;'static str 类型才能匹配参数的类型。这就是问题所在。

    错误是告诉你caps_off_.as_slice() 不能分配给caps_off,因为借来的切片的寿命不够长。那是因为bar.to_ascii_lower() 返回一个String,并且该字符串仅在函数调用期间存在。这意味着您不能将 Map.find() 与此值一起使用。

    幸运的是,HashMap 上还有另一种方法可以解决您的问题:find_equiv。通过使用它,编译器可以为 caps_off 推断出与您尝试分配给它的表达式 (&amp;'a str) 兼容的不同类型。只需更改foo 中的最后一行即可使用它:

    *my_foos.find_equiv(&caps_off).clone().unwrap()
    

    其实你甚至不需要调用as_slice(),你可以直接传递bar.to_ascii_lower()返回的String,如果只使用一次小写字符串就不需要定义变量:

    *my_foos.find_equiv(&bar.to_ascii_lower()).clone().unwrap()
    

    【讨论】:

      【解决方案2】:

      您应该发布您的完整代码以便我们理解错误,但是在该代码中,编译器无法判断新字符串的生存时间。 所以尝试一下:

      fn foo(bar: &'static str) -> Foo {
        let caps_off_ = bar.to_ascii_lower();
        let caps_off  = caps_off_.as_slice();
        ...
      }
      

      所以caps_off_ 在您使用切片时持有新的String 对象。

      编辑:

      除了上一个答案,正如 Francis 解释的那样,您声明地图的密钥是 &amp;'static str,因此 find 不会接受与同一签名不匹配的密钥。所以你有两个选择 1) 将地图声明为 &lt;&amp;str, Foo&gt; 而没有静态生命周期或 2) 使用 find_equiv 方法。

      希望对您有所帮助。

      【讨论】:

      • 请看上面的完整代码。这非常令人困惑。有没有办法可以手动告诉编译器“我还没有使用caps_off”?
      • 如果你放了一个我可以编译的代码来显示你的错误,我可以帮助你。它一定是关于生命的。
      • 好的,当然。请看我的编辑。代码现在应该可以编译了
      猜你喜欢
      • 2014-12-26
      • 2020-07-23
      • 1970-01-01
      • 2019-11-29
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多