生命周期的概念
生命周期這個(gè)概念其他語言中沒有,可能是爭(zhēng)議最大的Rust的特性了。
生命周期的存在主要是為了解決空懸指針的問題,也就是對(duì)象釋放掉了,但是還保留著指針,這個(gè)時(shí)候指針就指向NULL
Rust 1.0之前的版本沒有生命周期自動(dòng)推導(dǎo),之后rust的團(tuán)隊(duì)發(fā)現(xiàn)在某些模式下完全沒有必要手動(dòng)寫出生命周期,可以由編譯器自動(dòng)推導(dǎo)。在函數(shù)內(nèi)部的變量可以自動(dòng)確定生命周期,但是涉及到傳入的參數(shù)和傳出的參數(shù)時(shí),rust不能夠確認(rèn)生命周期,因此需要我們手動(dòng)確認(rèn)
編寫rust函數(shù)需要注意函數(shù)內(nèi)的變量的生命周期不能比函數(shù)外的變量的生命周期長(zhǎng)。
普通函數(shù)中自動(dòng)省略了<'a>位置和泛型的位置一樣,可以理解為泛型生命周期,因?yàn)榭梢越o多個(gè)輸入變量指定生命周期,注意函數(shù)中的生命周期只是一個(gè)標(biāo)注,不能改變實(shí)際參數(shù)的生命周期。
一個(gè)生命周期的例子如下,程序執(zhí)行到x=&f.x下一條程序時(shí),f自動(dòng)釋放了,這時(shí)候x就指向了null,就是一個(gè)空懸指針,編譯器會(huì)報(bào)錯(cuò)。
struct Foo<'a> {
x: &'a i32,
}
fn main() {
let x; // -+ x goes into scope
// |
{ // |
let y = &5; // ---+ y goes into scope
let f = Foo { x: y }; // ---+ f goes into scope
x = &f.x; // | | error here
} // ---+ f and y go out of scope
// |
println!("{}", x); // |
} // -+ x goes out of scope
生命周期的三原則
生命周期省略有三條基本原則,符合這三條基本原則的函數(shù)就可以自動(dòng)推導(dǎo)生命周期,其他情況就需要我們手動(dòng)指定。
- 每一個(gè)被省略的函數(shù)參數(shù)都有一個(gè)自己的且不同的生命周期參數(shù)。
沒有指定的情況下默認(rèn)每個(gè)函數(shù)的參數(shù)都有一個(gè)自己的生命周期值'a 'b 'c 依此類推。 - 如果剛好有一個(gè)輸入生命周期,不管是否省略,這個(gè)生命周期被賦予所有函數(shù)返回值中被省略的生命周期。
如果在函數(shù)聲明的時(shí)候手動(dòng)指定了一個(gè)<'a>那么,默認(rèn)所有省略的參會(huì)之都是這個(gè)生命周期。 - 如果有多個(gè)輸入生命周期,不過它們當(dāng)中有一個(gè)是&self或者&mut self,self的生命周期被賦予所有省略的輸出生命周期。
只要有&self或&mut self,那么所有的強(qiáng)制所有參數(shù)和返回值的生命周期都為self的生命周期。
舉個(gè)例子
fn longest(x:&str,y:&str) -> &str{
if x.len()>y.len() {
x
}else {
y
}
}
這段函數(shù)會(huì)報(bào)錯(cuò)。

因?yàn)榘凑杖瓌t的第一條,會(huì)自動(dòng)給x和y分配不同生命周期a和b,那么不能確定返回值的生命周期是什么。因此會(huì)報(bào)錯(cuò)。
改為
fn longest(x:&'a str,y:&'b str) -> &str {
}
此時(shí)就會(huì)返回x和y中生命周期最短的那個(gè)。雖然x和y傳入的參數(shù)的生命周期可能不同,但是在函數(shù)中x和y生命周期相同,都為最短的那個(gè)。