最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust?所有權機制原理深入剖析

 更新時間:2023年01月03日 14:01:52   作者:ooooooh灰灰  
這篇文章主要為大家介紹了Rust?所有權機制原理深入剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

what's ownership?

常見的高級語言都有自己的 Garbage Collection(GC)機制來管理程序運行的內存,例如 Java、Go 等。而 Rust 引入了一種全新的內存管理機制,就是 ownership(所有權)。它在編譯時就能夠保證內存安全,而不需要 GC 來進行運行時的內存回收。

在 Rust 中 ownership 有以下幾個規(guī)則:

  • 每個值都有一個 woner(所有者)
  • 在同一時間,每個值只能有一個 owner
  • 當 owner 離開作用域,這個值就會被丟棄

Scope (作用域)

通過作用域來劃分 owner 的生命周期,作用域是一段代碼的范圍,例如函數(shù)體、代碼塊、if 語句等。當 owner 離開作用域,這個值就會被丟棄

example:

fn main() {
    let s = String::from("hello"); // 變量 s 進入作用域,分配內存
    // s 在這里可用
} // 函數(shù)體結束,變量 s 離開作用域,s 被丟棄,內存被回收

ownership transfer(所有權轉移)

和大多數(shù)語言一樣,Rust 在棧上分配基本類型的值,例如整型、浮點型、布爾型等。而在堆上分配復雜類型的值,例如 String、Vec 等。所以,這里就引入了兩個概念,moveclone。

move

move 操作會將變量的所有權轉移給另一個變量,這樣原來的變量就不能再使用了。這里需要注意的是,move 操作只會發(fā)生在棧上的值,因為在堆上的值是不可復制的,所以只能通過 clone 操作來復制。

example:

fn main(){
    let s1 = String::from("hello");
    let s2 = s1;
    print!("s1 = {}, s2 = {}", s1, s2);
}

在上面的代碼例子中,如果你執(zhí)行就會在編譯時報錯:

  --> src/main.rs:11:32
   |
9  |     let s1 = String::from("hello");
   |         -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
10 |     let s2 = s1;
   |              -- value moved here
11 |     print!("s1 = {}, s2 = {}", s1, s2);
   |                                ^^ value borrowed here after move

編譯器提示我們,s1 在賦值給 s2 時發(fā)生了 move 的操作,它把字符串 hello 的所有權移交給了 s2,此時 s1 的作用域到這里就結束了,所以后面再使用 s1 就會報錯。

clone

clone 操作會將變量的值復制一份,這樣原來的變量和新的變量就都可以使用了。

這里需要注意的是,clone 操作只會發(fā)生在堆上的值,因為在棧上的值是可復制的,所以只能通過 move 操作來轉移所有權。

example:

fn main(){
    let s1 = String::from("hello");
    let s2 = s1.clone();
    print!("s1 = {}, s2 = {}", s1, s2);
}

我們對 s1 進行 clone 操作,這樣 s1s2 都可以使用了,而且 s1 的所有權也沒有被轉移,所以后面還可以繼續(xù)使用 s1。

copy

如果一個類型實現(xiàn)了 copy 這個 trait,使用它的變量不會移動,而是被簡單地復制,使它們在分配給另一個變量后仍然有效。

example:

fn main() {
    let x = 5;
    let y = x;
    print!("x = {}, y = {}", x, y);
}

x 賦值給 y 后,xy 都可以使用,而且 x 的所有權也沒有被轉移,所以后面還可以繼續(xù)使用 x。這是因為 i32 這個類型實現(xiàn)了 copy 這個 trait,所以 x 的值被復制了一份,所以 xy 都可以使用。

以下這些數(shù)據(jù)類型實現(xiàn)了 copy 這個 trait:

  • 所有的整數(shù)類型,例如:u32i32。
  • 布爾類型,bool,有 truefalse 兩個值。
  • 所有的浮點數(shù)類型,例如:f64、f32。
  • 字符類型,char。
  • 元組,當且僅當它們的元素類型都實現(xiàn)了 copy 這個 trait。例如,(i32, i32) 實現(xiàn)了 copy,但是 (i32, String) 就沒有實現(xiàn)。

References and Borrowing(引用和借用)

我們將創(chuàng)建引用的動作稱為借用。就像在現(xiàn)實生活中一樣,如果一個人擁有某樣東西,你可以向他們借用。完成后,您必須將其歸還。你不擁有它。 引用有以下幾個規(guī)則:

  • 在任何給定時間,你可以擁有任意數(shù)量的引用,但是只能擁有一個可變引用。
  • 引用必須總是有效的。

example1:

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
    s.len()
} // s 作用域失效,但是由于 s 是一個引用,沒有所有權,所以不會發(fā)生任何事情

上面代碼中,我們使用符號 & 來創(chuàng)造一個變量的引用。這里我們使用 &s1 來把這個引用指向 s1。函數(shù) calculate_length 的參數(shù) s 的類型是 &String,這意味著它是一個指向 String 類型的引用,然后在函數(shù)體內獲取 s 的長度并返回給調用者。

example2:

fn main(){
    // 同一時間可以擁有多個不可變引用
    let s1 = String::from("hello");
    let s2 = &s1;
    let s3 = &s1;
    println!("s1 = {}, s2 = {}, s3 = {}", s1, s2, s3);
}

Mutable References(可變引用)

可變引用指的是可以改變引用值的引用。在同一作用域中,同一時間只能有一個可變引用。

example:

fn main(){
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);
}
fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

上面代碼中,我們用 mut 先創(chuàng)建了一個可變變量 s,然后使用 &mut s 創(chuàng)建了一個指向 s 的可變引用。函數(shù) change 的入參也是一個指向 String 類型的可變引用,這樣我們就可以在函數(shù) change 中改變 s 的值了。

example2:

fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &mut s;  // 在這里。編譯器會報錯,因為在同一作用域中,同一時間只能有一個可變引用。
    println!("{}, {}", r1, r2);
}
  --> src/main.rs:41:14
   |
40 |     let r1 = &mut s;
   |              ------ first mutable borrow occurs here
41 |     let r2 = &mut s;
   |              ^^^^^^ second mutable borrow occurs here
42 |
43 |     println!("{}, {}", r1, r2);
   |                        -- first borrow later used here

Dangling References(懸垂引用)

懸垂引用是指引用一個不存在的值。在 Rust 中,這是不可能的,因為編譯器會在編譯時就檢查這種情況。下面是一個例子:

fn main() {
    let reference_to_nothing = dangle(); // 獲得一個指向不存在值的引用
}
fn dangle() -> &String {
    let s = String::from("hello"); // s 進入作用域
    &s // 返回 s 的引用
} // s 作用域結束,s 被丟棄,內存被釋放
  --> src/main.rs:51:16
   |
51 | fn dangle() -> &String {
   |                ^ expected named lifetime parameter

因為變量 s 的作用域只在 dangle 函數(shù)內,當 dangle 函數(shù)返回 s 的引用時,s 已經被釋放了,所以這個引用就是懸垂引用了。 解決這個的方法是返回一個 String 而不是一個引用,這樣 s 就不會被釋放,而是把 s 的所有權轉移給了調用者,也就不存在懸垂引用了。

fn dangle() -> String {
    let s = String::from("hello");
    s
}

以上就是Rust 所有權機制原理深入剖析的詳細內容,更多關于Rust 所有權機制的資料請關注腳本之家其它相關文章!

相關文章

  • rust中trait的使用方法詳解

    rust中trait的使用方法詳解

    trait用中文來講就是特征,它就是一個標記,只不過這個標記被用在特定的地方,也就是類型參數(shù)的后面,下面我們就來學習一下trait的具體使用方法吧
    2023-12-12
  • Rust控制流運算符match的用法詳解

    Rust控制流運算符match的用法詳解

    match 是Rust中一個極為強大的控制流運算符,用于模式匹配和控制流的選擇,它允許將一個值與一系列的模式相比較,根據(jù)匹配的模式執(zhí)行相應代碼,本文給大家詳細介紹了Rust控制流運算符match的用法,需要的朋友可以參考下
    2024-01-01
  • Rust Atomics and Locks并發(fā)基礎理解

    Rust Atomics and Locks并發(fā)基礎理解

    這篇文章主要為大家介紹了Rust Atomics and Locks并發(fā)基礎理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Rust常用功能實例代碼匯總

    Rust常用功能實例代碼匯總

    通過一系列實用示例展示了Rust在文件操作、網絡請求、并發(fā)編程、命令行工具以及數(shù)據(jù)庫操作等方面的應用,這些示例不僅展示了 Rust 的強大功能,還提供了實際開發(fā)中的指導和參考,通過這些示例,您可以更好地理解 Rust 的特性,并將其應用于您的項目中
    2024-12-12
  • 關于Rust?使用?dotenv?來設置環(huán)境變量的問題

    關于Rust?使用?dotenv?來設置環(huán)境變量的問題

    在項目中,我們通常需要設置一些環(huán)境變量,用來保存一些憑證或其它數(shù)據(jù),這時我們可以使用dotenv這個crate,接下來通過本文給大家介紹Rust?使用dotenv來設置環(huán)境變量的問題,感興趣的朋友一起看看吧
    2022-01-01
  • 一文帶你了解Rust是如何處理錯誤的

    一文帶你了解Rust是如何處理錯誤的

    程序在運行的過程中,總是會不可避免地產生錯誤,而如何優(yōu)雅地解決錯誤,也是語言的設計哲學之一。本文就來和大家來了Rust是如何處理錯誤的,感興趣的可以了解一下
    2022-11-11
  • rust的nutyp驗證和validator驗證數(shù)據(jù)的方法示例詳解

    rust的nutyp驗證和validator驗證數(shù)據(jù)的方法示例詳解

    本文介紹了在Rust語言中,如何使用nuType和validator兩種工具來對Cargo.toml和modules.rs文件進行驗證,通過具體的代碼示例和操作步驟,詳細解釋了驗證過程和相關配置,幫助讀者更好地理解和掌握使用這兩種驗證工具的方法,更多Rust相關技術資訊,可繼續(xù)關注腳本之家
    2024-09-09
  • Rust語言從入門到精通系列之Iterator迭代器深入詳解

    Rust語言從入門到精通系列之Iterator迭代器深入詳解

    這篇文章主要為大家介紹了Rust語言從入門到精通系列之Iterator迭代器深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • 使用Rust開發(fā)小游戲完成過程

    使用Rust開發(fā)小游戲完成過程

    這篇文章主要介紹了使用Rust開發(fā)小游戲的完整過程,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11
  • Rust使用Trait對象實現(xiàn)多態(tài)的詳細步驟

    Rust使用Trait對象實現(xiàn)多態(tài)的詳細步驟

    本文詳細介紹了在Rust中使用Trait對象實現(xiàn)運行時多態(tài)的方法,通過一個圖形渲染系統(tǒng)的案例展示了如何統(tǒng)一管理不同類型的圖形對象,文章涵蓋了Trait對象的核心概念、語法、性能考量以及在實際項目中的應用場景,感興趣的朋友跟隨小編一起看看吧
    2025-11-11

最新評論

永城市| 永新县| 射阳县| 革吉县| 淅川县| 塔城市| 五大连池市| 苗栗县| 浑源县| 额济纳旗| 镇平县| 辽阳县| 西藏| 二连浩特市| 师宗县| 改则县| 安丘市| 翼城县| 宣威市| 呼玛县| 中牟县| 四会市| 武定县| 贵州省| 泸溪县| 永泰县| 盱眙县| 伽师县| 古交市| 潼关县| 梓潼县| 吐鲁番市| 曲靖市| 白城市| 永昌县| 新昌县| 杭锦后旗| 嘉义县| 临江市| 孝感市| 固原市|