深入了解Rust的生命周期
Rust生命周期簡介
Rust 中的每一個引用都有其 生命周期(lifetime),也就是引用保持有效的作用域。
生命周期的主要目標是避免懸垂引用,它會導致程序引用了非預期引用的數(shù)據(jù)。
{ let r; { let x = 5; r = &x; } //x出作用域后已經(jīng)被刪除,發(fā)生懸垂引用 println!("r: {}", r); }
實現(xiàn)生命周期檢查的手段:Rust 編譯器有一個 借用檢查器(borrow checker),它比較作用域來確保所有的借用都是有效的。
//函數(shù)中的泛型生命周期 fn longest(x: &str, y: &str) -> &str { if x.len() > y.len() { x } else { y } } //該函數(shù)會發(fā)生編譯錯誤,因為 Rust 并不知道將要返回的引用是指向 x 或 y //當我們定義這個函數(shù)的時候,并不知道傳遞給函數(shù)的具體值,所以也不知道到底是 if 還是 else 會被執(zhí)行。 //我們也不知道傳入的引用的具體生命周期,所以也就不能通過觀察作用域來確定返回的引用是否總是有效。 //借用檢查器自身同樣也無法確定,因為它不知道 x 和 y 的生命周期是如何與返回值的生命周期相關聯(lián)的。
生命周期標注語法:
生命周期語法是用于將函數(shù)的多個參數(shù)與其返回值的生命周期進行關聯(lián)的。一旦他們形成了某種關聯(lián),Rust 就有了足夠的信息來允許內存安全的操作并阻止會產(chǎn)生懸垂指針亦或是違反內存安全的行為。
Q:為什么有這個語法?
A:因為編譯器笨,借用檢查器不知道類似上述情況中的生命周期怎么比較,所以靠人手寫給他約束。
生命周期標注并不改變任何引用的生命周期的長短。與當函數(shù)簽名中指定了泛型類型參數(shù)后就可以接受任何類型一樣,當指定了泛型生命周期后函數(shù)也能接受任何生命周期的引用。生命周期標注描述了多個引用生命周期相互的關系,而不影響其生命周期。
生命周期標注有著一個不太常見的語法:生命周期參數(shù)名稱必須以撇號('
)開頭,其名稱通常全是小寫,類似于泛型其名稱非常短。'a
是大多數(shù)人默認使用的名稱。生命周期參數(shù)標注位于引用的 &
之后,并有一個空格來將引用類型與生命周期標注分隔開。
//使用泛型生命周期標注語法解決上述問題 fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } //現(xiàn)在函數(shù)簽名表明對于某些生命周期 'a,函數(shù)會獲取兩個參數(shù),他們都是與生命周期 'a 存在的一樣長的字符串 slice。 //函數(shù)會返回一個同樣也與生命周期 'a 存在的一樣長的字符串 slice。 //它的實際含義是 longest 函數(shù)返回的引用的生命周期與傳入該函數(shù)的引用的生命周期的較小者一致。 //這就是我們告訴 Rust 需要其保證的約束條件。 //兩個直觀的例子 //1.正確示例:返回的引用生命周期與較小的string2一致,函數(shù)調用正確 fn main() { let string1 = String::from("long string is long"); { let string2 = String::from("xyz"); let result = longest(string1.as_str(), string2.as_str()); println!("The longest string is {}", result); } } //2.錯誤示例:返回的引用生命周期與string2一致,但是println時,result引用生命周期已經(jīng)結束,編譯失敗 fn main() { let string1 = String::from("long string is long"); let result; { let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); } println!("The longest string is {}", result); }
類似的,結構體,方法中使用到引用時也可以使用生命周期標注語法。
題外話:Rust觀法有在盡力的減輕開發(fā)者負擔,一些很常見的需要生命周期標注的情況,編譯器已經(jīng)在內部實現(xiàn)好了,未來用戶只會越來越少的使用到生命周期標注語法。被Rust 官方考慮到的一些引用分析的模式被稱為 生命周期省略規(guī)則(lifetime elision rules)。
比較特殊的,'static
,其生命周期能夠存活于整個程序期間。所有的字符串字面量都擁有 'static
生命周期。
//static生命周期 let s: &'static str = "I have a static lifetime.";
總結:
生命周期概念和大多數(shù)語言一樣,但Rust對變量生命周期的檢查是很具有特色的,還有他特別的生命周期標注語法是很性新穎的,能在編譯期處理的錯誤絕不留到運行時這是Rust很棒的設計理念.
到此這篇關于深入了解Rust的生命周期的文章就介紹到這了,更多相關Rust生命周期內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vscode搭建rust開發(fā)環(huán)境的圖文教程
本文主要介紹了vscode搭建rust開發(fā)環(huán)境的圖文教程,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-08-08