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

Rust 所有權(quán)(Ownership)的使用小結(jié)

 更新時(shí)間:2026年01月14日 09:48:54   作者:FAFU_ppg  
Rust通過所有權(quán)系統(tǒng)管理內(nèi)存,確保安全且無運(yùn)行時(shí)性能損失,所有權(quán)系統(tǒng)的核心規(guī)則包括唯一所有者、所有權(quán)失效時(shí)值自動(dòng)釋放和值在任何時(shí)刻只能有一個(gè)所有者,本教程詳細(xì)介紹了所有權(quán)的規(guī)則、棧與堆的區(qū)別以及所有權(quán)在變量賦值、函數(shù)傳參和返回值中的應(yīng)用

在rust編程中,內(nèi)存管理是核心挑戰(zhàn)之一。不同編程語言采用不同策略處理內(nèi)存,而 Rust 獨(dú)有的所有權(quán)系統(tǒng),在編譯期就能確保內(nèi)存安全,且不影響運(yùn)行時(shí)性能。本教程將從內(nèi)存管理背景出發(fā),逐步講解所有權(quán)的核心概念、規(guī)則及實(shí)踐應(yīng)用。

一、內(nèi)存管理的三種流派

所有程序都需與內(nèi)存交互,如何申請、釋放內(nèi)存是語言設(shè)計(jì)的關(guān)鍵。目前主流內(nèi)存管理方式分為三類:

管理方式核心邏輯典型語言優(yōu)缺點(diǎn)分析
垃圾回收(GC)程序運(yùn)行時(shí)自動(dòng)掃描“不再使用的內(nèi)存”并釋放Java、Go優(yōu)點(diǎn):無需手動(dòng)管理;缺點(diǎn):運(yùn)行時(shí)性能損耗
手動(dòng)管理內(nèi)存通過代碼顯式調(diào)用函數(shù)申請(如 malloc)和釋放(如 free)內(nèi)存C++優(yōu)點(diǎn):性能可控;缺點(diǎn):易出現(xiàn)內(nèi)存泄漏、野指針
所有權(quán)系統(tǒng)(Ownership)編譯器通過預(yù)設(shè)規(guī)則在編譯期檢查內(nèi)存使用,無運(yùn)行時(shí)開銷Rust優(yōu)點(diǎn):兼顧安全與性能;缺點(diǎn):需理解新規(guī)則

Rust 選擇所有權(quán)系統(tǒng),核心優(yōu)勢是:內(nèi)存安全檢查僅在編譯期執(zhí)行,運(yùn)行時(shí)無任何性能損失。

二、前置知識:棧(Stack)與堆(Heap)

Rust 的所有權(quán)規(guī)則與內(nèi)存存儲位置(棧/堆)緊密相關(guān),理解二者差異是掌握所有權(quán)的基礎(chǔ)。

1. 棧(Stack):有序、高效的內(nèi)存區(qū)域

棧是后進(jìn)先出(LIFO) 的數(shù)據(jù)結(jié)構(gòu),類似“疊盤子”——新數(shù)據(jù)放在頂部,取數(shù)據(jù)也從頂部開始,無法直接操作中間數(shù)據(jù)。

  • 存儲要求:數(shù)據(jù)大小必須已知且固定(編譯期可確定)。
  • 操作效率:極高。入棧(存數(shù)據(jù))、出棧(取數(shù)據(jù))僅需移動(dòng)“棧指針”,無需復(fù)雜計(jì)算。
  • 典型存儲數(shù)據(jù):基本類型(如 i32、bool)、函數(shù)參數(shù)、局部變量。

2. 堆(Heap):靈活、無序的內(nèi)存區(qū)域

堆用于存儲大小未知或動(dòng)態(tài)變化的數(shù)據(jù)。當(dāng)需要存儲數(shù)據(jù)時(shí),程序會(huì)向操作系統(tǒng)申請一塊“足夠大的空閑內(nèi)存”,操作系統(tǒng)標(biāo)記該內(nèi)存為“已使用”并返回內(nèi)存地址(指針),程序再將指針存入棧中。

  • 存儲流程:申請內(nèi)存(分配)→ 操作系統(tǒng)返回指針 → 指針存入棧 → 通過指針訪問堆數(shù)據(jù)。
  • 操作效率:較低。分配內(nèi)存時(shí)需操作系統(tǒng)尋找空閑區(qū)域,訪問數(shù)據(jù)需先通過棧指針跳轉(zhuǎn),步驟更多。
  • 典型存儲數(shù)據(jù):動(dòng)態(tài)大小類型(如 String、數(shù)組)。

3. 棧與堆的性能對比

對比維度棧(Stack)堆(Heap)
分配速度極快(僅移動(dòng)棧指針)較慢(需操作系統(tǒng)查找空閑內(nèi)存)
訪問速度快(直接訪問)較慢(需通過棧指針跳轉(zhuǎn))
數(shù)據(jù)大小要求固定且已知(編譯期確定)可動(dòng)態(tài)變化(運(yùn)行時(shí)確定)
自動(dòng)釋放函數(shù)結(jié)束后自動(dòng)出棧釋放需手動(dòng)/所有權(quán)系統(tǒng)管理釋放

三、所有權(quán)的核心規(guī)則

所有權(quán)是 Rust 管理堆內(nèi)存的核心機(jī)制,必須牢記以下三條規(guī)則

  1. Rust 中每一個(gè)值都被一個(gè)變量“擁有”,該變量稱為值的所有者。
  2. 一個(gè)值同時(shí)只能有一個(gè)所有者(即“唯一所有權(quán)”)。
  3. 當(dāng)所有者(變量)離開作用域時(shí),該值會(huì)被自動(dòng)丟棄(調(diào)用 drop 函數(shù)釋放內(nèi)存)。

1. 變量作用域:所有權(quán)的“生命周期”

作用域是變量的“有效范圍”——變量從聲明處開始生效,離開作用域后失效(觸發(fā) drop 釋放內(nèi)存)。這一點(diǎn)與其他語言(如 Java、C++)類似。

示例代碼

#![allow(unused)]
fn main() {
    // 作用域1:s尚未聲明,無效
    {                     
        let s = "hello";   // 作用域2:s聲明,開始生效
        println!("{}", s); // 有效:可使用s
    }                      // 作用域2結(jié)束:s失效,自動(dòng)釋放內(nèi)存
    // 作用域1:s已失效,無法使用
}

四、所有權(quán)的實(shí)踐:以 String 類型為例

字符串是理解所有權(quán)的最佳案例——Rust 中有兩種字符串類型:

  • 字符串字面值(&str):硬編碼到程序中的不可變字符串(如 "hello"),存儲在“常量區(qū)”,無需堆內(nèi)存。
  • String 類型:動(dòng)態(tài)可變字符串(如 String::from("hello")),存儲在堆中,需所有權(quán)管理。

下面通過 String 類型,講解所有權(quán)的核心交互場景。

1. 場景1:轉(zhuǎn)移所有權(quán)(Move)

當(dāng)變量綁定到“堆上數(shù)據(jù)”(如 String)時(shí),賦值操作會(huì)觸發(fā)所有權(quán)轉(zhuǎn)移,而非數(shù)據(jù)拷貝。

為什么不直接拷貝?

String 由三部分組成(存儲在棧中):

  • ptr:指向堆中字符串內(nèi)容的指針;
  • len:字符串當(dāng)前長度(已使用的內(nèi)存);
  • capacity:字符串的總?cè)萘浚ǚ峙涞亩褍?nèi)存大?。?/li>

若賦值時(shí)拷貝整個(gè) String(包括堆中數(shù)據(jù)),會(huì)產(chǎn)生深拷貝,對性能消耗極大(尤其大字符串)。因此 Rust 采用“所有權(quán)轉(zhuǎn)移”策略:

所有權(quán)轉(zhuǎn)移示例

#![allow(unused)]
fn main() {
    let s1 = String::from("hello"); // s1 是 "hello" 的所有者
    let s2 = s1;                    // 所有權(quán)從 s1 轉(zhuǎn)移到 s2
    // println!("{}", s1);          // 錯(cuò)誤!s1 已失效,無法使用
    println!("{}", s2);             // 正確!s2 是當(dāng)前所有者
}

轉(zhuǎn)移后邏輯

  • s1 不再指向堆中數(shù)據(jù),變?yōu)?ldquo;無效狀態(tài)”;
  • 只有 s2 擁有堆中數(shù)據(jù)的所有權(quán);
  • 當(dāng) s2 離開作用域時(shí),自動(dòng)調(diào)用 drop 釋放堆內(nèi)存,避免“二次釋放”(內(nèi)存安全 bug)。

2. 場景2:克?。–lone):主動(dòng)深拷貝

若確實(shí)需要“完整拷貝堆中數(shù)據(jù)”(深拷貝),可使用 clone 方法。這是 Rust 中唯一主動(dòng)觸發(fā)深拷貝的方式,需顯式調(diào)用(避免無意識的性能損耗)。

克隆示例

#![allow(unused)]
fn main() {
    let s1 = String::from("hello"); 
    let s2 = s1.clone(); // 深拷貝:棧中 String 結(jié)構(gòu) + 堆中字符串內(nèi)容均拷貝
    
    println!("s1 = {}, s2 = {}", s1, s2); // 正確!s1 仍有效(未轉(zhuǎn)移所有權(quán))
}

注意:clone 性能開銷較大,僅在必要時(shí)使用(如初始化程序、低頻操作),避免在“熱點(diǎn)代碼”(高頻執(zhí)行邏輯)中調(diào)用。

3. 場景3:拷貝(Copy):棧上數(shù)據(jù)的自動(dòng)淺拷貝

對于棧中存儲的基本類型(如 i32、bool),賦值操作會(huì)自動(dòng)觸發(fā)“淺拷貝”——拷貝數(shù)據(jù)本身(而非轉(zhuǎn)移所有權(quán)),原變量仍有效。

這是因?yàn)闂V袛?shù)據(jù)大小固定、拷貝速度極快,無需通過“所有權(quán)轉(zhuǎn)移”管理。Rust 為這類類型實(shí)現(xiàn)了 Copy 特征,標(biāo)記其支持“自動(dòng)拷貝”。

拷貝示例

#![allow(unused)]
fn main() {
    let x = 5; // 基本類型 i32,存儲在棧中
    let y = x; // 自動(dòng)拷貝:棧中數(shù)據(jù) 5 復(fù)制給 y,x 仍有效
    
    println!("x = {}, y = {}", x, y); // 正確!x 和 y 均有效
}

支持Copy特征的類型

滿足“大小固定、無需堆內(nèi)存”的類型均支持 Copy,常見類型包括:

  • 所有整數(shù)類型(u8、i32、u64 等);
  • 布爾類型(bool);
  • 所有浮點(diǎn)數(shù)類型(f32、f64);
  • 字符類型(char);
  • 元組(僅當(dāng)所有元素均支持 Copy 時(shí),如 (i32, bool) 支持,(i32, String) 不支持);
  • 不可變引用(&T,如 &str);

注意:可變引用(&mut T)不支持 Copy,避免多個(gè)可變引用修改同一數(shù)據(jù)導(dǎo)致沖突。

五、函數(shù)中的所有權(quán)

函數(shù)傳參和返回值的過程,同樣遵循所有權(quán)規(guī)則——本質(zhì)與變量賦值一致(轉(zhuǎn)移或拷貝)。

1. 函數(shù)傳參:所有權(quán)的轉(zhuǎn)移/拷貝

  • 若傳入堆上類型(如 String):所有權(quán)從調(diào)用方轉(zhuǎn)移到函數(shù)參數(shù),調(diào)用方后續(xù)無法使用該變量;
  • 若傳入棧上類型(如 i32):自動(dòng)拷貝,調(diào)用方仍可使用原變量。

示例代碼

fn main() {
    let s = String::from("hello");  // s 是 String 所有者(堆上數(shù)據(jù))
    takes_ownership(s);             // 所有權(quán)轉(zhuǎn)移到函數(shù)參數(shù) some_string,s 失效
    // println!("{}", s);          // 錯(cuò)誤!s 已失效

    let x = 5;                      // x 是 i32(棧上數(shù)據(jù))
    makes_copy(x);                  // 自動(dòng)拷貝,x 仍有效
    println!("x = {}", x);          // 正確!x 未轉(zhuǎn)移所有權(quán)
}

// 接收 String 類型參數(shù):參數(shù)進(jìn)入作用域時(shí)獲得所有權(quán)
fn takes_ownership(some_string: String) {
    println!("{}", some_string);
} // some_string 離開作用域,調(diào)用 drop 釋放堆內(nèi)存

// 接收 i32 類型參數(shù):參數(shù)是 Copy 類型,拷貝后原變量仍有效
fn makes_copy(some_integer: i32) {
    println!("{}", some_integer);
} // some_integer 離開作用域,無堆內(nèi)存需釋放

2. 函數(shù)返回值:所有權(quán)的傳遞

函數(shù)返回值會(huì)將所有權(quán)傳遞給“接收返回值的變量”,本質(zhì)是“轉(zhuǎn)移所有權(quán)”。

示例代碼

fn main() {
    // 1. 函數(shù)返回 String,所有權(quán)轉(zhuǎn)移給 s1
    let s1 = gives_ownership();     

    // 2. s2 是 String 所有者
    let s2 = String::from("hello");  
    // 3. s2 所有權(quán)轉(zhuǎn)移到函數(shù),函數(shù)返回后轉(zhuǎn)移給 s3
    let s3 = takes_and_gives_back(s2); 
    // println!("{}", s2);          // 錯(cuò)誤!s2 已轉(zhuǎn)移所有權(quán)
}

// 返回 String:將 some_string 的所有權(quán)轉(zhuǎn)移給調(diào)用方
fn gives_ownership() -> String {
    let some_string = String::from("hello"); 
    some_string // 隱式返回,所有權(quán)轉(zhuǎn)移
}

// 接收 String 并返回:先獲得 a_string 的所有權(quán),再轉(zhuǎn)移給調(diào)用方
fn takes_and_gives_back(a_string: String) -> String {
    a_string // 所有權(quán)轉(zhuǎn)移給調(diào)用方
}

六、總結(jié)

1. 核心要點(diǎn)回顧

  • 所有權(quán)是 Rust 解決內(nèi)存安全的核心機(jī)制,編譯期檢查,無運(yùn)行時(shí)開銷;
  • 三條核心規(guī)則:唯一所有者、所有者失效則值釋放、值僅一個(gè)所有者;
  • 堆上類型(如 String)賦值觸發(fā)所有權(quán)轉(zhuǎn)移,棧上類型(如 i32)賦值觸發(fā)自動(dòng)拷貝;
  • 函數(shù)傳參/返回值遵循所有權(quán)規(guī)則,本質(zhì)是“轉(zhuǎn)移或拷貝”。

到此這篇關(guān)于Rust 所有權(quán)(Ownership)的使用小結(jié)的文章就介紹到這了,更多相關(guān)Rust 所有權(quán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入了解Rust中函數(shù)與閉包的使用

    深入了解Rust中函數(shù)與閉包的使用

    本文主要介紹一下Rust函數(shù)相關(guān)的內(nèi)容,首先函數(shù)我們其實(shí)一直都在用,所以函數(shù)本身沒什么可說的,我們的重點(diǎn)是與函數(shù)相關(guān)的閉包、高階函數(shù)、發(fā)散函數(shù),感興趣的可以學(xué)習(xí)一下
    2022-11-11
  • Rust中的引用與借用舉例詳解

    Rust中的引用與借用舉例詳解

    這篇文章主要給大家介紹了關(guān)于Rust中引用與借用的相關(guān)資料,rust中借用和引用的附帶功效都一樣,就是都有生命周期,文中通過代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Rust具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-11-11
  • Rust結(jié)構(gòu)體的定義與實(shí)例化詳細(xì)講解

    Rust結(jié)構(gòu)體的定義與實(shí)例化詳細(xì)講解

    結(jié)構(gòu)體是一種自定義的數(shù)據(jù)類型,它允許我們將多個(gè)不同的類型組合成一個(gè)整體。下面我們就來學(xué)習(xí)如何定義和使用結(jié)構(gòu)體,并對比元組與結(jié)構(gòu)體之間的異同,需要的可以參考一下
    2022-12-12
  • rust中的match表達(dá)式使用詳解

    rust中的match表達(dá)式使用詳解

    在rust中提供了一個(gè)極為強(qiáng)大的控制流運(yùn)算符match,這篇文章主要介紹了rust中的match表達(dá)式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Rust你不認(rèn)識的所有權(quán)

    Rust你不認(rèn)識的所有權(quán)

    所有權(quán)對大多數(shù)開發(fā)者而言是一個(gè)新穎的概念,它是 Rust 語言為高效使用內(nèi)存而設(shè)計(jì)的語法機(jī)制。所有權(quán)概念是為了讓 Rust 在編譯階段更有效地分析內(nèi)存資源的有用性以實(shí)現(xiàn)內(nèi)存管理而誕生的概念
    2023-01-01
  • 一文掌握Rust編程中的生命周期

    一文掌握Rust編程中的生命周期

    在Rust語言中, 每一個(gè)引用都有其生命周期, 通俗講就是每個(gè)引用在程序執(zhí)行的過程中都有其自身的作用域, 一旦離開其作用域, 其生命周期也宣告結(jié)束, 值不再有效,這篇文章主要介紹了Rust編程中的生命周期,需要的朋友可以參考下
    2023-11-11
  • 淺析Rust多線程中如何安全的使用變量

    淺析Rust多線程中如何安全的使用變量

    這篇文章主要為大家詳細(xì)介紹了Rust如何在線程的閉包中安全的使用變量,包括共享變量和修改變量,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下
    2025-01-01
  • Rust利用tauri制作個(gè)效率小工具

    Rust利用tauri制作個(gè)效率小工具

    日常使用電腦中經(jīng)常會(huì)用到一個(gè)quicke工具中的輪盤菜單工具。但quicke免費(fèi)版很多功能不支持,且它的觸發(fā)邏輯用的不舒服,經(jīng)常誤觸。所以本文就來用tauri自制一個(gè)小工具,希望對大家有所幫助
    2023-02-02
  • rust 包模塊組織結(jié)構(gòu)詳解

    rust 包模塊組織結(jié)構(gòu)詳解

    RUST提供了一系列的功能來幫助我們管理代碼,包括決定哪些細(xì)節(jié)是暴露的、哪些細(xì)節(jié)是私有的,以及不同的作用域的命名管理,這篇文章主要介紹了rust 包模塊組織結(jié)構(gòu)的相關(guān)知識,需要的朋友可以參考下
    2023-12-12
  • 關(guān)于Rust編譯時(shí)報(bào)link.exe?not?found錯(cuò)誤問題

    關(guān)于Rust編譯時(shí)報(bào)link.exe?not?found錯(cuò)誤問題

    這篇文章主要介紹了Rust編譯的時(shí)候報(bào)出link.exe?not?found錯(cuò)誤問題,解決方法是在命令行就是CMD執(zhí)行相應(yīng)的命令即可,本文給大家分解決方法,需要的朋友可以參考下
    2022-09-09

最新評論

沂水县| 宜川县| 衡南县| 沁源县| 天镇县| 安多县| 渝中区| 大方县| 炎陵县| 监利县| 洮南市| 天津市| 雷山县| 新建县| 合肥市| 台湾省| 攀枝花市| 丹棱县| 泰安市| 翁牛特旗| 宣汉县| 绍兴市| 井陉县| 蛟河市| 长寿区| 宣武区| 乌什县| 灵丘县| 嵊泗县| 黎平县| 师宗县| 奎屯市| 厦门市| 临澧县| 荥经县| 玉溪市| 鲁甸县| 彩票| 滦平县| 莲花县| 安溪县|