Rust生命週期

生命週期定義了引用有效的範圍。
生命週期是隱含的和推斷的。
Rust使用通用生命週期參數來確保使用有效的實際引用。

預防與生命週期的懸空引用

當程序試圖訪問無效引用時稱爲懸空引用,所指向無效資源的指針稱爲懸空指針。

看看一個簡單的例子:

fn main()  
{  
  let a;  
  {  
    let b = 10;  
     a = &b;  
  }  
  println!("a : {}",a);  
}

輸出結果如下 -

Rust生命週期

在上面的示例中,外部作用域包含a變量,並且它不包含任何值。 內部範圍包含變量b,它存儲的值爲10b變量的引用存儲在變量a中。 當內部範圍結束時,嘗試訪問a的值。 Rust編譯器將拋出一個編譯錯誤,因爲a變量指的是變量的位置超出了範圍。 Rust將使用借用檢查器確定代碼無效。

借用檢查器

借用檢查器用於解決懸掛引用的問題。 借用檢查器用於比較範圍以確定它們是否有效。

Rust生命週期

在上面的例子中,註釋了a變量的生命週期,ab變量的生命週期帶有b變量。 在編譯時,Rust將拒絕該程序,因爲a變量的生命週期大於b變量的生命週期。 可以修復上面的代碼,以便不會發生編譯器錯誤。

Rust生命週期

在上面的例子中,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.

在上述情況下,引用xy都具有相同的生命週期,即'a

當引用具有不同的生命週期時。如下 -

fn fun<'a , 'b>(x: & 'a i32 , y: & 'b i32)   

   // block of code.

在上述情況下,參考xy都具有不同的生命週期,即分別爲'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.