Rust生命週期
生命週期定義了引用有效的範圍。
生命週期是隱含的和推斷的。
Rust使用通用生命週期參數來確保使用有效的實際引用。
預防與生命週期的懸空引用
當程序試圖訪問無效引用時稱爲懸空引用,所指向無效資源的指針稱爲懸空指針。
看看一個簡單的例子:
fn main()
{
let a;
{
let b = 10;
a = &b;
}
println!("a : {}",a);
}
輸出結果如下 -
在上面的示例中,外部作用域包含a
變量,並且它不包含任何值。 內部範圍包含變量b
,它存儲的值爲10
。b
變量的引用存儲在變量a
中。 當內部範圍結束時,嘗試訪問a
的值。 Rust編譯器將拋出一個編譯錯誤,因爲a
變量指的是變量的位置超出了範圍。 Rust將使用借用檢查器確定代碼無效。
借用檢查器
借用檢查器用於解決懸掛引用的問題。 借用檢查器用於比較範圍以確定它們是否有效。
在上面的例子中,註釋了a
變量的生命週期,a
和b
變量的生命週期帶有b
變量。 在編譯時,Rust將拒絕該程序,因爲a
變量的生命週期大於b
變量的生命週期。 可以修復上面的代碼,以便不會發生編譯器錯誤。
在上面的例子中,a
變量的生命週期短於b
變量的生命週期。 因此,上面的代碼運行時沒有任何編譯錯誤。
生命週期註釋語法
- 生命週期註釋不會改變任何引用的生存時間。
- 函數還可以使用泛型生存期參數接受任何生命週期的引用。
- 生命週期註釋描述了多個參數的生命週期之間的關係。
生命週期註釋語法應遵循的步驟:
- 生命週期參數的名稱應以(
'
)撇號開頭。 - 它們主要是小寫和簡寫。 例如:
'a
。 - 生命週期參數註釋放在引用的
&
之後,然後是空格以將註釋與引用類型分開。
生命週期註釋語法的一些示例:
-
&i32
// reference -
& 'a i32
// reference with a given lifetime. -
& 'a mut i32
// mutable reference with a given lifetime.
函數簽名中的生命週期註釋
'a
代表參考的生命週期。每個參考都有與之相關的生命週期。也可以在函數簽名中使用生命週期註釋。 通用生命週期參數在角括號<>
之間使用,角括號放在函數名和參數列表之間。
示例 -
fn fun<'a>(...);
在上面的例子中,fun
是具有一個生命週期的函數名,即'a
。 如果函數包含兩個具有兩個不同生命週期的參考參數,則它可以表示爲:
fn fun<'a,'b>(...);
如果'y'
是不可變引用,那麼參數列表將是:
fn fun<'a>(y : & 'a i32);
如果'y'
是可變引用,那麼參數列表將是:
fn fun<'a>(y : & 'a mut i32);
兩個&'a i32
和&'a mut i32
都很相似。 唯一的區別是'a
放在&
和mut
之間。
&mut i32
的意思是「對i32的可變引用」。&'a mut i32
表示「對具有生命週期’的i32
的可變引用」。
結構中的生命週期註釋
也可以在結構中使用顯式生命週期,就像在函數中使用的一樣。
下面來看看一個示例:
struct Example
x : & 'a i32, // x is a variable of type i32 that has the lifetime 'a.
下面來看一個簡單的例子:
struct Example<'a> {
x: &'a i32,
}
fn main() {
let y = &9;
let b = Example{ x: y };
println!("{}", b.x);
}
執行上面示例代碼,得到以下結果 -
9
impl塊
可以實現具有生命週期'a
使用impl
塊的結構類型。
下面來看一個簡單的例子:
struct Example<'a> {
x: &'a i32,
}
impl<'a> Example<'a>
{
fn display(&self)
{
print!("Value of x is : {}",self.x);
}
}
fn main() {
let y = &90;
let b = Example{ x: y };
b.display();
}
執行上面示例代碼,得到以下結果 -
Value of x is : 90
多個生命週期
有兩種可能性:
- 多個引用具有相同的生命週期。
- 多個引用具有不同的生命週期。
當引用具有相同的生命週期時。
fn fun <'a>(x: & 'a i32 , y: & 'a i32) -> & 'a i32
//block of code.
在上述情況下,引用x
和y
都具有相同的生命週期,即'a
。
當引用具有不同的生命週期時。如下 -
fn fun<'a , 'b>(x: & 'a i32 , y: & 'b i32)
// block of code.
在上述情況下,參考x
和y
都具有不同的生命週期,即分別爲'a
和'b
。
‘static
'static
的生命週期是特殊的生命週期。它表示某些東西具有生命週期'static
將在整個程序中具有生命週期。 主要是'static
生命週期與字符串一起使用。 具有「靜態生命週期」的引用對整個程序有效。
示例 :
let s : & 'static str = "Yiibai tutorial" ;
生命週期橢圓
生命週期橢圓是一種推理算法,它使常見的模式更符合人體工程學。生命週期橢圓使一個程序被淘汰。
生命週期橢圓可以在任何地方使用:
-
& 'a T
-
& 'a mut T
-
T<'a>
生命週期橢圓可以以兩種方式出現:
- 輸入生命週期:輸入生命週期是與函數參數關聯的生命週期。
- 輸出生存期:輸出生存期是與函數返回類型關聯的生命週期。
示例 -
fn fun<'a>( x : & 'a i32); // input lifetime
fn fun<'a>() -> & 'a i32; // output lifetime
fn fun<'a>(x : & 'a i32)-> & 'a i32; // Both input and output lifetime.