[為你自己學 Rust] 生命週期(Lifetime)
![[為你自己學 Rust] 生命週期(Lifetime)](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBczBDIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7f9afb910d545ee422773358043b08e91d4a20f0/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBPZ2hxY0djNkUzSmxjMmw2WlY5MGIxOW1hV3hzV3dkcEFnQUZhUUpBQVE9PSIsImV4cCI6bnVsbCwicHVyIjoidmFyaWF0aW9uIn19--dae5f865966589ea53e128cb7972bbf3965c434c/kaochenlong_lifetime_258a9dd6-5c05-49b0-80e1-ec00e3315870.jpg)
在前面的「所有權(Ownership)」章節曾經介紹 Rust 是如何透過所有權的轉讓與出借,來決定是否要釋放不再使用的記憶體空間,但其實在介紹所有權的時候,我們有省略了一些東西。
Rust 有「借(Borrow)」的設計,不需要複製整份資料,只要用 &
做個參照或切片,就能透過參照直接取用原本的資料。但是想像一下,如果我做了一個 Slice 指向某個 Vector,萬一那個 Vector 因為某些因素被放掉了,那麼這個 Slice 會參照到什麼東西?原本指向的記憶體位置讓出來之後假設運氣好沒有被其它資料佔用的話,也許有機會拿回來,但萬一被其它資料佔用了呢?Rust 編譯器為了確保程式可以正確執行,所以不會允許這種懸空參照(dangling reference)可能造成的不確定性,在編譯階段就會直接被擋下來。
所以如果要正常運作的話,被指到的 Vector 就不能比參照它的 Slice 還早消失對吧。Rust 的編譯器有一個 Borrow Checker(以下簡稱 BC)的設計,它會檢查參照的生命週期,如果 Rust 編譯器發現參照的資料的生命週期比較短,也就是會比較早消失,編譯就不會通過。雖然 BC 的檢查可能會有點囉嗦甚至難理解,但它可以避免常見的像是「使用後釋放(use-after-free)」或「雙重釋放(double-free)」的記憶體問題,也是它被說是比較「安全」的原因。