Rust 的生命週期
今天我們要來介紹其他程式語言中比較少見的機制,但是在 Rust 中是屬於和參考(reference)有關的機制,那就是生命週期(lifetime)。
一、生命週期的概念
生命週期是 Rust 中的一個概念,它是一個變數的有效範圍,也就是它可以被使用的範圍。生命週期的概念是為了解決 Rust 中的參考的問題,因為參考是 Rust 中的一個重要機制,它可以讓開發者在不需要複製資料的情況下,就可以使用資料。但是參考也有一個問題,就是它的生命週期,也就是它的有效範圍,如果參考的資料已經被釋放了,那麼參考就會變成一個無效的參考,這樣就會造成程式的錯誤。
這裡有一個範例:
1 | { |
先說結論,這個範例是沒辦法通過編譯的,也就是會報錯。
這是因為我們先宣告了一個變數 r,然後我們在一個新的區塊中宣告了一個變數 x,並且將 x 的參考賦值給 r。
這個時候,x 的生命週期就結束了,但是 r 仍然使用 x 的參考,這樣就會造成程式的錯誤。
二、生命週期的標記
- 生命週期的標記不會改變參考的生命週期,它只是用來標記參考的生命週期,讓 Rust 編譯器可以知道這個參考的生命週期是多少。
- 當指定了泛型生命週期參數後,函式就可以接收帶有任何生命週期的參考。
在語法上有以下幾個重點:
生命週期參數名稱:
- 以單引號
'
開頭 - 一般以全部小寫字母命名
- 大部分的慣例都使用
'a
作為生命週期參數名稱
- 以單引號
生命週期標記的位置:
- 在參考的
&
符號之後 - 使用空格將生命週期與參考分開
- 在參考的
看一下以下的範例:
1 | &i32 // 一個參考 |
單一個生命週期標記是沒有意義的,這是因為標記生命週期是為了要讓 Rust 編譯器知道多個參考的生命週期之間的關係,所以如果只有一個參考,那麼就沒有必要標記生命週期。
以下是一個範例:
1 | fn longer<'a>(s1: &'a str, s2: &'a str) -> &'a str { |
這個函式接收兩個參考,並且回傳一個參考,這個函式的生命週期參數名稱是 'a
,這個生命週期參數名稱被用在了函式的參數與回傳值上,這樣就可以讓 Rust 編譯器知道這三個參考的生命週期是相同的。
最後在執行這個函式的時候就不會問題,並且可以正常執行:
1 | fn main() { |
三、生命週期的規則
在 Rust 中,生命週期的規則有三個:
- 每個參考都有一個生命週期
- 每個參考都有一個作用域
- 一個參考的生命週期不能超過它的作用域
總結
Rust 的生命週期跟所有權,兩者在其語言中的資源管理機制上都是非常重要的。由於參考是 Rust 在對於複雜類型中不可少的機制,而每個參考都有其生命週期,這是為了決定該參考是否有效的作用域。
前面有提到 Rust 的型別大多數其實都可以自動判別,而生命週期其實也一樣,都是可以自動推導出來。不過當生命週期以不同方式互相牽連的狀態下,開發者就要自行設定,這也跟型別非常複雜的狀態下,開發者就要自行設定型別一樣。
以上就是 Rust 的生命週期的基本概念,希望大家對 Rust 又更了解了一些。