rust中的lifetime到底是什麼?

時間 2021-05-11 20:33:19

1樓:匿蟒

首先,lifetime合適的翻譯是生存期,不是生命週期(lifecycle)。它是一條命,沒有週期性。

其次,乙個記憶體資源,從它出現,到被丟棄(drop),這就是從生到死,這之間即其生存期。

'a 屬於lifetime標記。lifetime標記通常以 ' 開頭,後面以abcd來區分。fnf

<'a,

'b>(v1: &

'aT1

,v2: &

'bT2

)-> &

'aT3

這個函式生命表明,返回值的lifetime,與第乙個引數v1是相同的。

如果沒有這個標記,編譯器會根據函式內容取推斷,但這不一定準確。預設行為是,在函式f返回時,v1和v2都被drop了。如果返回值與v1有關,而又沒有推斷出來,那就有問題了,所以需要主動標記一下。

letv3=f

(v4,v5

)v4和v5作為引用,在函式呼叫的那一刻,就已經被drop了。

v1和v2作為引用,在函式f執行完畢時,被drop了。

v2所引用的owner,其lifetime此後僅受自身維持。如果在函式f後沒有呼叫,那麼也一起被drop了。

v1所引用的owner,lifetime被標記為與返回值相同。因此它會在v3被drop後,被編譯器drop。

如果發明「殉情」和「改嫁」的概念,也許更容易解釋。

v2的owner可能為v2殉情,因為她可能孤苦無依;但v1的owner卻不會,因為在遺囑裡,她被指定改嫁給v3了。

2樓:蟋蟀大叔

是為了防止懸垂指標引用的存在,而對設計出的物件及函式的契約,於是編譯器幫你檢查,什麼時候必須加上契約,才安全,呼叫者是否滿足這個契約。 而這個契約是從變數的生存週期方向考慮的設計的。生命週期標註符號並不能改變生命週期,但是建立了一種契約,就好像我說只有1公尺8以下的同學才能通過這個門,但是通過這個門的人的同學的身高並沒有改變!

3樓:歐文韜

大致上就是編譯期告訴你啥時候析構、誰析構(構造和move)或者保證某個期間不析構(借用)。

所以問題裡,v1、v3的關係的話其實是只要其中乙個有效(未被析構)那麼另乙個也有效。v2和他們沒什麼關係,除非你加一些額外的生命週期宣告('b : 'a之類)。

然後v1的生命週期這裡會推斷為和v4一樣(v1==v4),同理v2和v5一樣(v2==v5)。因為按你的注釋的話都是借用型別。

再然後第二個問題,取決於你的函式宣告了。按你這裡的申明的話,其實第二個引數可以不申明生命週期的,一樣的。反正沒什麼強制關聯,但是你的申明的引數型別都是借用,所以在函式執行期間不能影響和轉移傳入物件的生命週期。

在函式體內返回值的有效期只要》='a就行,返回的時候生命週期的約束是可以自動縮小的,但不能放大。

4樓:

你要說到底是什麼,那麼 Y. Wang 早就說過了:對 Rust 語言的分析。

「實際上這個 lifetime 我感覺像是跨過程靜態分析時產生的一些標記。」——Y. Wang

這個標記在 Rust 中滿足一些代數性質,可以表達兩個 lifetime 之間的關係。

5樓:四維漢堡包

生命週期是一種保證,保證你的資料是有效的。

rust中的引用、Box、Rc、Arc。。。這些東西,本質上都是一種指標,大致可分為兩大類。

一類指標擁有資源(具有所有權),是尊貴的有產階級。所以它們可以控制資源的釋放,保證自己所指向的資料一直有效。

另一類指標借用資源,就比較苦逼了。它們指向的資源不是自己的,隨時可能因為指向的資源被別人釋放而陷入無資源可用的尷尬境地。此時我們管這種無處安放自己的指標叫『』野指標『』,這種指標內心帶著對程式的強烈怨念,是記憶體錯誤的元凶之一。

為了保證這些無產階級能夠一生平安,rust加入了生命週期的概念。通過保證資源的存留時間長於指向它的所有引用,即引用的生命周期短於資源,這些引用在它們的生命週期內所指向的資源一定存在。這就是生命週期的第乙個作用。

乙個結構體,本質上是乙個生死相依的團隊。如果這個結構體含有某個失效了的成員,所有通過結構體使用該成員的函式,都會面臨風險。因為這個短板,拖累了整個團隊。

解決思路同上,通過編譯期檢查,保證團隊在有成員無效之前散夥,即結構體的生命周期短於它的任一成員,由此保證結構體中的資料全部有效。這是生命週期的第二個作用。

現在我們不妨假設乙個該死的引用r,它可能同時借用a和b管理的資源,選擇結果直到執行時才能決定。那麼它的生命週期是什麼呢?

答案是兩個可能生命週期中最短的那個。因為編譯檢查的時候無法確定r的借用關係,所以只能讓r在任何情況下都能滿足第乙個原則。即,如果引用可能借用多個資源,引用的生命週期小於以上任何乙個

函式可能會返回引用。但是這與之前有什麼不同呢?

首先,函式不能返回任何自己創造的引用。因為呼叫結束後,函式所創造的世界將會毀滅,函式管理的資源要麼被移動了,要麼被析構了。所以函式返回的引用,均來自呼叫者

引用指向呼叫者管理的資源,必然由呼叫者創造,受呼叫者的約束。但函式內部是乙個黑盒,不能確定引用的生命週期,那怎麼辦呢?

辦法是將引用在泛型中傳入,在函式內運算,保證呼叫函式的生命週期規則與直接寫scope一致,由此避免踩坑。

6樓:倪宇軒

還沒什麼使用經驗,看了一下文件,說下我自己的認知。

rust裡面函式預設是不能返回引用的(為了「安全」),但是能返回引數的引用。

如果有多個引數,你就得告訴編譯器返回的引用是跟著哪個引數的生命週期。

生命週期這個寫法可以看成給編譯器提供的資訊。

7樓:

lifetime 是放在尖括號裡的。Rust 的 lifetime 可以當做泛型系統的一部分。

fn f<'a, 'b>(v1: &'a T1, v2: &'b T2) -> &'a T3

這裡面的 'a 'b 是泛型引數,在這裡的意思就是一種約束,傳入兩個指標 v1 v2,返回乙個指標。v1 的 lifetime 和 v2 不同,但是和最終返回的指標相同。

let v3 = f(v4, v5)

這裡傳入 v4 v5 的時候,v4 的 lifetime 就會被推導成泛型的第乙個型別引數 'a,v5 的 lifetime 就會被推導成 'b。

也就是說,替換形參以後大概是這樣的

fn f<'v4, 'v5>(v4: &'v4 T1, v5: &'v5 T2) -> &'v4 T3

現在你的 v3,是乙個指向 T3 型別的指標,它的 lifetime 和 v4 相同,也就是說當 v4 銷毀的時候 v3 也銷毀。

8樓:鍾宇騰

你的v4和v5實際上只是省略了Lifetime的宣告,補全一下可以是v4: &'ltv4 T1

v5: &'ltv5 T2

然後呼叫的時候,就變成了

'a == 'ltv4

'b == 'ltv5

v1, v2, v3, v4, v5之間到底什麼關係?

呼叫的時候

v4 就是 v1

v5 就是 v2

v3 就是你函式的返回值

與上下文有關嗎?有。

Rust 中的 ptr Shared 使用問題?

根據文件 core ptr Shared Rust 和原始碼 ptr.rs.html source Shared 就是保證非 null 的 raw pointer,對比 raw pointer 的好處是不用檢查 null,然後有型別資訊。沒有任何開銷。鍊錶前驅和後繼不會被別的鍊錶共享,否則就是 Gr...

(翻譯)Rust中的設計模式 4 The Default Trait

滴滴答答 在我看來,恐婚的人應該分為四種,一種對婚後生活過於幻想期待,覺得應該去戀愛時期美好,有特別多期待,但是在身邊人或者網路中一些例子告訴你婚後生活那種繁雜瑣碎,生活的壓力,打破了你美好的幻想,因此恐婚。一種就是活的自我,始終堅信婚姻就是墳墓,覺得婚姻限制了自己的人身自由,不喜歡束縛的感覺,認為...

如何在Rust中寫Y組合子?

Nugine 這裡給出兩種實現。符合理論要求的 fny f implFn dynFn A O,A O implFn A O impl a,A,O Copy forX a,A,O impl a,A,O X a,A,O move a x X a x.call x a X x,a f a x.call x...