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

Rust 智能指針的實(shí)現(xiàn)

 更新時(shí)間:2026年06月24日 08:17:44   作者:菜鳥謝  
本文主要介紹了Rust智能指針的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

涵蓋:Box、Rc/Arc、RefCell/Mutex、Deref/Drop trait、循環(huán)引用等
重點(diǎn):智能指針選型、線程安全約束、內(nèi)部可變性、內(nèi)存泄漏預(yù)防

一、基礎(chǔ)概念

1. 普通裸指針*const T / *mut T

無所有權(quán)、無自動(dòng)內(nèi)存管理、無借用檢查,僅存內(nèi)存地址,操作必須 unsafe。

2. 智能指針本質(zhì)

實(shí)現(xiàn)了 Deref + Drop trait 的結(jié)構(gòu)體

  1. Deref:自動(dòng)解引用,像普通引用一樣使用;
  2. Drop:離開作用域自動(dòng)釋放堆內(nèi)存,防止內(nèi)存泄漏;
  3. 變量本體存在棧,棧內(nèi)只存指針/元數(shù)據(jù),真實(shí)數(shù)據(jù)存堆;
  4. 自帶所有權(quán)、借用、計(jì)數(shù)、鎖等安全邏輯,不用手動(dòng)管理內(nèi)存。

區(qū)分普通引用 & 智能指針

類型說明
&T借用,不擁有數(shù)據(jù),生命周期依附所有者
智能指針擁有堆數(shù)據(jù)所有權(quán),自行管理內(nèi)存生命周期

二、核心智能指針分類

獨(dú)占所有權(quán):Box

底層結(jié)構(gòu)

struct Box<T>(*mut T);

棧上僅一根堆指針,T 完整分配在堆。

核心特性

  1. 唯一所有者,同一時(shí)間只能有一個(gè) Box;
  2. 無額外開銷,性能等同于裸指針;
  3. 自動(dòng) Drop,出作用域釋放堆;
  4. 實(shí)現(xiàn) Deref<Target=T>,可直接 . 訪問字段。

適用場景

  1. 遞歸結(jié)構(gòu)體/枚舉(解決無限尺寸)
struct Node {
    val: i32,
    next: Option<Box<Node>>
}
  1. 超大棧值,避免棧溢出,轉(zhuǎn)移到堆;
  2. 構(gòu)造 trait 對象 Box<dyn Trait>(胖指針:數(shù)據(jù)指針 + vtable);
  3. FFI、需要堆分配的場景。

示例

let b = Box::new(10);
println!("{}", *b); // Deref 解引用
println!("{}", b);  // 自動(dòng)隱式解引用

單線程共享所有權(quán):Rc / Weak

Rc 底層

堆上分配 RcInner<T>,包含:

  • 強(qiáng)引用計(jì)數(shù) strong:持有數(shù)據(jù)的 Rc 數(shù)量;
  • 弱引用計(jì)數(shù) weak:Weak 數(shù)量;
  • 真實(shí)數(shù)據(jù) T。

規(guī)則

  1. Rc<T> 多份克隆共享同一堆數(shù)據(jù),單線程專用,不支持多線程;
  2. 每次 .clone() 僅??截愔羔槪焉?strong+1;
  3. 所有 Rc 銷毀 strong=0,釋放數(shù)據(jù);weak 不阻止釋放;
  4. 內(nèi)部不可變:Rc 只讀,如需修改搭配 RefCell<T>

Weak 弱指針

  1. 不增加強(qiáng)計(jì)數(shù),不阻止數(shù)據(jù)釋放;
  2. 調(diào)用 upgrade() 嘗試轉(zhuǎn)為 Option<Rc<T>>,數(shù)據(jù)已銷毀返回 None;
  3. 解決循環(huán)引用內(nèi)存泄漏。

示例

use std::rc::Rc;
let a = Rc::new("hello".to_string());
let b = Rc::clone(&a); // 僅計(jì)數(shù) +1,不拷貝字符串
println!("strong count: {}", Rc::strong_count(&a));

多線程共享所有權(quán):Arc / Weak

和 Rc 邏輯完全一致,區(qū)別:

特性RcArc
計(jì)數(shù)方式普通整數(shù)原子操作 AtomicUsize
線程安全? 單線程? 跨線程
性能開銷略高(原子指令)

搭配內(nèi)部可變性:Arc<Mutex<T>> / Arc<RwLock<T>>

內(nèi)部可變性容器(棧存指針,堆存標(biāo)記 + 數(shù)據(jù))

1. RefCell 單線程內(nèi)部可變性

突破外部不可變限制,運(yùn)行時(shí)借用檢查(而非編譯期)

  • 存儲(chǔ):堆存數(shù)據(jù) + 借用狀態(tài)標(biāo)記(借出數(shù)量、是否可變)
  • 方法:
    • .borrow()Ref<T> 不可變借用(可多個(gè)同時(shí)存在)
    • .borrow_mut()RefMut<T> 可變借用(同一時(shí)間只能一個(gè))
  • 違反規(guī)則運(yùn)行時(shí) panic,非編譯報(bào)錯(cuò)。

搭配 Rc 實(shí)現(xiàn)單線程共享可變數(shù)據(jù):Rc<RefCell<T>>

use std::rc::Rc;
use std::cell::RefCell;
let val = Rc::new(RefCell::new(0));
*val.borrow_mut() += 1;

2. Cell

內(nèi)部可變性,只適合 Copy 小類型

  • 小 Copy 類型直接棧存儲(chǔ),無堆分配;
  • 無借用,直接 .get() / .set(),不會(huì)觸發(fā) panic;
  • 不能包裹 String、Vec 非 Copy 類型。

3. Mutex 互斥鎖(多線程)

多線程內(nèi)部可變性,同一時(shí)間僅一個(gè)線程訪問數(shù)據(jù):

  • .lock() 獲取鎖,返回 MutexGuard<T>,阻塞等待;
  • 中毒:持有鎖線程 panic,鎖永久失效;
  • 搭配 Arc:Arc<Mutex<T>> 多線程共享可變資源。

4. RwLock 讀寫鎖

  • 多個(gè)讀共存,寫?yīng)氄?;讀多寫少場景性能優(yōu)于 Mutex。

三、Deref 自動(dòng)解引用(智能指針核心 trait)

Deref trait 定義

trait Deref {
    type Target;
    fn deref(&self) -> &Self::Target;
}

實(shí)現(xiàn)后支持:

  1. *智能指針 手動(dòng)解引用;
  2. 自動(dòng)隱式解引用,直接調(diào)用內(nèi)部字段/方法;
  3. 解引用強(qiáng)制轉(zhuǎn)換:函數(shù)傳參自動(dòng)逐層解引用。

示例:Box 自動(dòng)解引用

struct Point { x: i32, y: i32 }
let p = Box::new(Point { x: 1, y: 2 });
println!("{}", p.x); // 自動(dòng) deref,無需 *p

DerefMut 可變解引用

trait DerefMut: Deref {
    fn deref_mut(&mut self) -> &mut Self::Target;
}

Box<T>、RefMut、MutexGuard 均實(shí)現(xiàn),支持 *mut_ptr = xxx 修改。

四、Drop 析構(gòu) trait

所有所有權(quán)智能指針都實(shí)現(xiàn) Drop,離開作用域自動(dòng)執(zhí)行:

智能指針Drop 行為
Box釋放堆上 T
Rc/Arcstrong 計(jì)數(shù) -1,計(jì)數(shù)歸零釋放堆
RefCell/Mutex釋放內(nèi)部堆數(shù)據(jù)

手動(dòng)提前釋放:std::mem::drop(x),主動(dòng)轉(zhuǎn)移所有權(quán)觸發(fā) Drop。

五、智能指針選型對照表

指針線程安全所有權(quán)模式可變性方案典型用途
Box單/多線程均可獨(dú)占唯一外部 mut遞歸類型、堆分配、trait 對象
Rc? 單線程共享多所有者Rc<RefCell>單線程多層共享
Arc? 多線程共享多所有者Arc<Mutex/RwLock>跨線程共享資源
RefCell? 單線程獨(dú)占運(yùn)行時(shí)借用檢查單線程內(nèi)部可變性
Mutex? 多線程獨(dú)占互斥排他訪問多線程可變共享
RwLock? 多線程獨(dú)占讀共享寫排他讀多寫少并發(fā)
Weak跟隨 Rc/Arc弱引用不計(jì)數(shù)解決循環(huán)引用

六、關(guān)鍵使用規(guī)則

1. 所有權(quán)與拷貝

指針行為
Boxmove 語義,賦值轉(zhuǎn)移所有權(quán);clone 深拷貝堆數(shù)據(jù)
Rc/Arc.clone() 僅增加計(jì)數(shù),零堆拷貝
Weak不能直接使用,必須 upgrade 轉(zhuǎn) Rc/Arc

2. 循環(huán)引用泄漏問題

單純 Rc/Arc 雙向引用會(huì)造成計(jì)數(shù)永遠(yuǎn)不為 0,內(nèi)存泄漏;

解決:其中一端改用 Weak 弱指針。

3. 線程安全約束 Send / Sync

指針Send/Sync
BoxT 滿足 Send/Sync 則 Box 滿足
Rc不實(shí)現(xiàn) Send/Sync,禁止跨線程
Arc實(shí)現(xiàn) Send+Sync,可跨線程
MutexSend+Sync

4. 解引用強(qiáng)制多態(tài)(函數(shù)傳參自動(dòng)轉(zhuǎn)換)

fn read(s: &str) {}
let b = Box::new("test".to_string());
read(&b);
// &Box<String> → &String → &str 自動(dòng)多層 deref

七、高頻易錯(cuò)點(diǎn)

?? 以下易錯(cuò)點(diǎn)需特別注意

  1. Rc 傳給 spawn 線程直接編譯報(bào)錯(cuò),必須換 Arc;
  2. RefCell 在同一作用域同時(shí)存在可變 + 不可變借用,運(yùn)行時(shí) panic;
  3. 忘記循環(huán)引用搭配 Weak,長期運(yùn)行內(nèi)存持續(xù)上漲;
  4. Mutex lock() 在線程 panic 后鎖中毒,后續(xù)全部阻塞;
  5. Box::new 超大數(shù)組會(huì)先在棧構(gòu)造再拷貝堆,超大數(shù)組優(yōu)先 Vec;
  6. 混淆借用 &T 和智能指針:&無所有權(quán),智能指針擁有堆內(nèi)存;
  7. Cell 僅支持 Copy 類型,包裹 String 編譯報(bào)錯(cuò)。

八、速記口訣

智能指針實(shí)現(xiàn) Deref+Drop,棧存指針堆存數(shù)據(jù);
Box 獨(dú)占單所有者,遞歸 trait 對象必備;
Rc 單線程共享,Arc 多線程原子計(jì)數(shù);
Weak 弱引用防循環(huán)泄漏,upgrade 轉(zhuǎn)為強(qiáng)指針;
RefCell 單線程內(nèi)部可變,運(yùn)行借用檢查;
Mutex/RwLock 多線程鎖,讀寫分離性能更佳;
Deref 自動(dòng)解引用,點(diǎn)號直接訪問內(nèi)部字段;
Rc 禁止跨線程,跨線程共享只用 Arc。

到此這篇關(guān)于Rust 智能指針的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Rust 智能指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust指南之生命周期機(jī)制詳解

    Rust指南之生命周期機(jī)制詳解

    Rust?生命周期機(jī)制是與所有權(quán)機(jī)制同等重要的資源管理機(jī)制,之所以引入這個(gè)概念主要是應(yīng)對復(fù)雜類型系統(tǒng)中資源管理的問題,這篇文章主要介紹了Rust指南之生命周期機(jī)制詳解,需要的朋友可以參考下
    2022-10-10
  • vscode搭建rust開發(fā)環(huán)境的圖文教程

    vscode搭建rust開發(fā)環(huán)境的圖文教程

    Rust 是一種系統(tǒng)編程語言,它專注于內(nèi)存安全、并發(fā)和性能,本文主要介紹了vscode搭建rust開發(fā)環(huán)境的圖文教程,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Rust重載運(yùn)算符之復(fù)數(shù)四則運(yùn)算的實(shí)現(xiàn)

    Rust重載運(yùn)算符之復(fù)數(shù)四則運(yùn)算的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了Rust如何實(shí)現(xiàn)復(fù)數(shù)以及復(fù)數(shù)的四則運(yùn)算,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • 如何使用bindgen將C語言頭文件轉(zhuǎn)換為Rust接口代碼

    如何使用bindgen將C語言頭文件轉(zhuǎn)換為Rust接口代碼

    這篇文章主要介紹了使用bindgen將C語言頭文件轉(zhuǎn)換為Rust接口代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例

    libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例

    這篇文章主要為大家介紹了libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • rust 中的 EBNF簡介舉例

    rust 中的 EBNF簡介舉例

    這篇文章主要介紹了rust 中的 EBNF簡介舉例,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-05-05
  • rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法

    rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法

    本文給出了一個(gè)通用的設(shè)計(jì)模式,通過建造者模式實(shí)例化記錄對象,可自定義格式化器將實(shí)例化后的記錄對象寫入到指定的緩存對象中,這篇文章主要介紹了rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法,需要的朋友可以參考下
    2024-04-04
  • Rust調(diào)用函數(shù)操作符?.?和?::?的區(qū)別詳解

    Rust調(diào)用函數(shù)操作符?.?和?::?的區(qū)別詳解

    在Rust中,.和::操作符都可以用來調(diào)用方法,但它們的用法有所不同,所以本文就將詳細(xì)的給大家介紹一下.和::操作符的區(qū)別,感興趣的同學(xué)跟著小編一起來學(xué)習(xí)吧
    2023-07-07
  • Rust?編程語言中的所有權(quán)ownership詳解

    Rust?編程語言中的所有權(quán)ownership詳解

    這篇文章主要介紹了Rust?編程語言中的所有權(quán)ownership詳解的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 如何基于Rust實(shí)現(xiàn)文本搜索minigrep

    如何基于Rust實(shí)現(xiàn)文本搜索minigrep

    這篇文章主要介紹了基于Rust實(shí)現(xiàn)的文本搜索minigrep,本次演示介紹針對原作者代碼程序的查詢邏輯做了一點(diǎn)點(diǎn)小的優(yōu)化,原程序邏輯的查詢是放在了程序運(yùn)行的時(shí)候,邏輯修改后啟動(dòng)的時(shí)候可以添加參數(shù),也可以啟動(dòng)后添加,需要的朋友可以參考下
    2024-08-08

最新評論

元氏县| 定安县| 怀来县| 九江市| 邹城市| 从化市| 苍南县| 股票| 瓮安县| 虎林市| 惠州市| 仙游县| 韶山市| 贡山| 德安县| 德格县| 山阴县| 呼伦贝尔市| 华池县| 陵水| 靖宇县| 塔河县| 磴口县| 镇宁| 绥芬河市| 云霄县| 辽阳县| 丹凤县| 赣州市| 富川| 南木林县| 锦屏县| 栾川县| 乐东| 德兴市| 永安市| 喀喇| 夏邑县| 彰化县| 凤阳县| 南阳市|