2017-02-15 48 views
0

這是我的第一個Rust代碼。僅僅因爲編譯器告訴我,我將生命週期參數添加到內部函數中。雖然我理解Rust書中的終身解釋,但我不能自己寫這個簽名。爲什麼我需要這些壽命,但不需要其他人,如何知道正確的簽名以及如何識別需要壽命的參數?

fn transform_the_expression() { 
    fn create_formula<'t>(formula: & mut HashMap<& str, &'t str>, input: &'t str, re: Regex)->std::borrow::Cow<'t, str>{ 
     let replacement = re.find(input).unwrap(); 
     formula.insert("1", replacement.as_str()); 
     let rest = re.replace(input, "1"); 
     return rest; 
    } 

    let input = "(a+(b*c))"; 
    use regex::Regex; 
    let re = Regex::new(r"\([\w\d][/*+-^][\w\d]\)").unwrap(); 
    use std::collections::HashMap; 
    let mut formula = HashMap::new(); 

    let result = create_formula(&mut formula, input, re); 

    println!("result = {:?}", result); 

} 
  • 爲什麼我需要在簽名這3位生存期?
  • 爲什麼我不需要他們在其他地方?
  • 我該如何去編寫沒有編譯器告訴我該怎麼做的正確簽名?
  • 如何識別需要壽命的參數?
+1

這種類型的問題並不適合堆棧溢出。對[Rust subreddit](https://www.reddit.com/r/rust),[用戶論壇](https://users.rust-lang.org/)或[IRC] (https://www.rust-lang.org/en-US/community.html) – Shepmaster

回答

4

編譯器非常擅長告訴你什麼時候需要指定生命週期,但不一定非常擅長讓你知道哪些是生命週期。

首先,值得一提的是,有每個參考的生存期;只是有lifetime elision rules這說明編譯器如果不指定它們將如何填充它們。

返回到您的簽名:

fn create_formula(formula: & mut HashMap<& str, &str>, input: &str, re: Regex)->std::borrow::Cow<_, str> 

絕對需要的第一生存是一個在Cow<_, str>;你需要有一段時間才能宣佈這個功能。有兩種選擇:申報一個,或使用'static。在這種情況下,Cow可能指向input參數的一部分,因此您需要將它們綁定在一起。首先,新的生命週期需要通過函數名稱後添加<'t>(任何名稱會做),然後將其用於input和返回類型聲明:

fn create_formula<'t>(formula: & mut HashMap<& str, &str>, input: &'t str, re: Regex)->std::borrow::Cow<'t, str> 

最後你把的input借用部分進入HashMap。如果input生命週期(我們現在命名爲't)與HashMap值沒有關係,那麼某個人可能會傳入一個散列圖,該散列圖的壽命比輸入長,這導致地圖中懸掛指針。因此,我們需要限制它也讓最終版本:

fn create_formula<'t>(formula: & mut HashMap<&str, &'t str>, input: &'t str, re: Regex)->std::borrow::Cow<'t, str> 

關鍵的一點是,函數簽名需要說服編譯器引用的所有使用是安全的,這往往意味着你必須要明確關於不同參考參數(和生命週期參數類型)之間的關係,當默認(通過elision規則)沒有說正確的事情時。

+0

非常感謝,這對我們有很大的幫助。 –

相關問題