原因

第一次碰到这个错毫无头绪,简化代码是这样的

  1. struct test_struct {
  2. }
  3. impl test_struct {
  4. fn return_string(&self) -> String {
  5. String::from("hello")
  6. }
  7. }
  8. fn main() {
  9. let t = test_struct{};
  10. let hello = t.return_string().as_str();
  11. println!("{}", hello);
  12. }
  1. error[E0716]: temporary value dropped while borrowed
  2. --> src/main.rs:36:17
  3. |
  4. 36 | let hello = t.return_string().as_str();
  5. | ^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
  6. | |
  7. | creates a temporary which is freed while still in use
  8. 37 | println!("{}", hello);
  9. | ----- borrow later used here
  10. |
  11. = note: consider using a `let` binding to create a longer lived value
  12. error: aborting due to previous error

对于其他语言来说这样的写法再正常不过了,但对于rust来说却无法编译通过,来分析一下原因

return_string 返回的是一个owned value,as_str() 返回的是&str,&str是String的引用,也就是说String一定要比&str活的长,如果String比&str提早drop,那么&str就指向一个空值。那return_string()后,String的生命周期是什么呢?

如果这段代码这样写就很清楚了

  1. let hello = {
  2. let __temp = t.return_string();
  3. __temp.as_str()
  4. }; // --> __temp die here

__temp在返回给hello就被drop了。

如何解决

解决办法很简单,写成两行就行了

  1. fn main() {
  2. let t = test_struct{};
  3. let returnstr = t.return_string();
  4. let hello = returnstr.as_str();
  5. println!("{}", hello);
  6. }
  1. let __temp = t.return_string();
  2. let hello = {
  3. __temp.as_str()
  4. }; // --> __temp lives long as hello