2015-04-05 88 views
1

的生命週期內有效我得到一生錯誤,並且無法理解問題是什麼。這是造成錯誤的代碼是:引用必須在塊的定義爲

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) 

什麼是與此功能的問題?

回答

4

您在函數中創建q,然後嘗試從函數返回對其的引用。由於q在您的函數結束時不再存在,返回值將是一個懸掛引用,這就是編譯器不會讓您這樣做的原因。

btw。你可以看到你的函數簽名會出現一些詭計。返回的引用('a)的生命週期實際上並不與任何東西(例如函數參數的生命週期)綁定,這表明這可能不起作用。

+0

如果我將賦值更改爲「let q:&'TempDir =&Tempdir ....」它仍然給我那個錯誤。我如何解決這個問題? – hunterboerner 2015-04-05 17:11:05

+0

是否確定要返回參考?爲什麼不按值返回'q'? – fjh 2015-04-05 17:13:22

+0

@hunterboerner,你根本不能返回一個對局部變量的引用。如果你這樣做,這個變量就會被銷燬,你將留下一個懸而未決的參考 - 這正是Rust想要阻止的。在C++中,這樣的代碼可能會給你一個段錯誤。 – 2015-04-05 19:13:12

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 
} 
+0

試過,它的工作原理。謝謝您的幫助。 – hunterboerner 2015-04-06 00:01:56

相關問題