参考必须对于块上定义的生命周期'a有效

时间:2015-04-05 17:03:45

标签: rust

我遇到了终身错误,无法理解问题所在。导致错误的代码是:

fn fetch_git_repo<'a>(repo_info: &RepoInfo) -> &'a TempDir {
    let q: TempDir = TempDir::new("temp_git_clone_dir").ok().unwrap();
    //let path: &str = dir.path().to_str().unwrap();

    let status = Command::new("git").arg("clone").arg(q.path().to_str().unwrap())
        .arg(&repo_info.repo_url).status().unwrap_or_else(|e| {
            panic!("Failed to run git clone: {}", e)
        });

    if !status.success() {
        panic!("Git clone failed!");
    }

    &q
}

错误本身就是:

test.rs:88:6: 88:7 error: `q` does not live long enough
test.rs:88     &q
                          ^
test.rs:75:60: 89:2 note: reference must be valid for the lifetime 'a as defined on the block at 75:59...
test.rs:75 fn fetch_git_repo<'a>(repo_info: &RepoInfo) -> &'a TempDir {
test.rs:76     let q: TempDir = TempDir::new("temp_git_clone_dir").ok().unwrap();
test.rs:77     //let path: &str = dir.path().to_str().unwrap();
test.rs:78 
test.rs:79     let status = Command::new("git").arg("clone").arg("")
test.rs:80         .arg(&repo_info.repo_url).status().unwrap_or_else(|e| {
                     ...
test.rs:76:70: 89:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 76:69
test.rs:76     let q: TempDir = TempDir::new("temp_git_clone_dir").ok().unwrap();
test.rs:77     //let path: &str = dir.path().to_str().unwrap();
test.rs:78 
test.rs:79     let status = Command::new("git").arg("clone").arg("")
test.rs:80         .arg(&repo_info.repo_url).status().unwrap_or_else(|e| {
test.rs:81             panic!("Failed to run git clone: {}", e)

这个功能的问题是什么?

2 个答案:

答案 0 :(得分:4)

您正在函数中创建q,然后尝试从函数中返回对它的引用。由于q在函数末尾不再存在,因此返回值将是一个悬空引用,这就是编译器不允许你这样做的原因。

顺便说一句。你可以从你的功能签名中看到一些狡猾的东西。返回引用('a)的生命周期实际上并不与任何事物(例如函数参数的生命周期)相关联,这表明这可能不起作用。

答案 1 :(得分:0)

我通过直接返回TempDir来解决这个问题。

fn fetch_git_repo(repo_info: &RepoInfo) -> TempDir {
    let z = TempDir::new("temp_git_clone_dir").unwrap();
    let q = z.path().to_str().unwrap().to_string();

    println!("{:?}", z.path());
    // omitted

    z
}