功能可变寿命qs

时间:2018-08-01 01:17:13

标签: rust lifetime

fn get_str1<'a>() -> &'a str {
    let x = "hello";
    return x;
}

fn get_str2<'a>(str1: &str) -> &'a str {
    let x: &'a str = (str1.to_string() + "123").as_str();
    return x;
}

fn get_str3<'a>(str1: &str) -> &'a str {
    let tmp = str1.to_string() + "123";
    let x: &'a str = tmp.as_str();
    return x;
}

#[test]
fn lifetime_test() {
    println!("{}", get_str1());
    println!("{}", get_str2("hello"));
    println!("{}", get_str3("hello"))
}

当我调用get_str1时,没有问题,但是当我调用get_str2时,它出现了编译错误:

error[E0597]: borrowed value does not live long enough
 --> src/main.rs:7:22
  |
7 |     let x: &'a str = (str1.to_string() + "123").as_str();
  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^         - temporary value only lives until here
  |                      |
  |                      temporary value does not live long enough
  |
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 6:1...
 --> src/main.rs:6:1
  |
6 | fn get_str2<'a>(str1: &str) -> &'a str {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: consider using a `let` binding to increase its lifetime

当我调用get_str3时,它也出现编译错误:

error[E0597]: `tmp` does not live long enough
  --> src/main.rs:13:22
   |
13 |     let x: &'a str = tmp.as_str();
   |                      ^^^ borrowed value does not live long enough
14 |     return x;
15 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 11:1...
  --> src/main.rs:11:1
   |
11 | fn get_str3<'a>(str1: &str) -> &'a str {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

为什么会出现这些错误以及如何解决get_str2get_str3

1 个答案:

答案 0 :(得分:1)

第一个函数起作用是因为字符串具有'static的生存期,并且将由编译器提升。

其他的..

fn get_str2<'a>(str1: &str) -> &'a str {
    let x = (str1.to_string() + "123").as_str();
    return x
}

这部分:str1.to_string(),不是返回字符串切片……而是String的新实例。基本上与此相同:

let x = str1.to_string(); // this is of type String, and its lifetime is local to this function
let y = str1 + "123"; // This consumes str1 and appends a &str to it - thus the lifetime is still of the new String instance above
let z = y.as_str(); // This returns a reference to the local String instance

阅读上面的每个注释,很明显,您实际上是在尝试返回对本地String的引用。您无法执行此操作,因为String将在函数末尾被破坏,并且引用将无效。

这也适用于您的第三个功能。您将返回对String实例的引用,该实例将在函数末尾销毁。