Rust 智能指針實(shí)現(xiàn)方法
Rust 第24節(jié) 智能指針
智能指針的實(shí)現(xiàn)
智能指針通常使用struct實(shí)現(xiàn),
并實(shí)現(xiàn)Deref和Drop這兩個trait
Deref trait:允許智能指針struct 的實(shí)例像引用一樣使用
Drop triat: 允許你自定義當(dāng)智能指針實(shí)例走出作用域時(shí)的代碼
標(biāo)準(zhǔn)庫中常見的智能指針
Box<T>:在heap內(nèi)存上分配值 Rc<T>: 啟用多重所有權(quán)的引用技術(shù)類型 Ref<T> RefMut<T> 通過RefCall<T> 訪問:在運(yùn)行時(shí)而不是編譯時(shí)強(qiáng)制借用規(guī)則的類型
使用Box 來指向Heap上的數(shù)據(jù)
他是最簡單的智能指針
let b = Box::new(5); println!("b = {}",b);
rust 編譯時(shí)需要知道一個類型所占的空間大小
但是遞歸類型的大小在編譯時(shí)無法確認(rèn)大小
使用Box可以解決,Box是指針,大小確認(rèn)
Deref Trait
Deref 解引用,我們可以自定義解引用運(yùn)算符*的行為
通過Deref,智能指針可以像常規(guī)引用一樣來處理
解引用運(yùn)算符
let x = 5; let y = &x; assert_eq!(5,x); assert_eq!(5,*y);
使用box
let y = Box::new(5); assert_eq!(5,*y);
自定義一個元組指針
struct Mypointer<T>(T); //結(jié)構(gòu)體元組,只有一個成員 //元組結(jié)構(gòu)體相當(dāng)于沒有成員名字的結(jié)構(gòu)體,通過索引訪問 impl<T> Mypointer<T> { fn new(x : T) -> Mypointer<T> { Mypointer(x) } } //要讓其成為指針,需要實(shí)現(xiàn)Deref方法 impl<T> Deref for Mypointer<T> { type Target = T; fn deref(&self) -> &T { &self.0 } } let y = Mypointer::new(5); assert_eq!(5,*y);
Deref 隱式解引用方法
當(dāng)傳入類型與函數(shù)接收類型不匹配時(shí),如果參數(shù)實(shí)現(xiàn)了Deref trait,則編譯器會自動調(diào)用Deref方法,對參數(shù)類型進(jìn)行匹配;
例子:
fn hello(name : & str) { println!("hello,{}",name); } hello("Rust"); let m = Mypointer::new(String::from("Rust")); //原始類型為 &mypointer<String> // deref &string // deref &str hello(&m);
Drop Trait
實(shí)現(xiàn)后,可以自定義值離開作用域時(shí)發(fā)生的動作
要求實(shí)現(xiàn)drop方法
在變量離開作用域時(shí),會自動調(diào)用drop方法
例子:
impl<T> Drop for Mypointer<T> { fn drop(&mut self) { println!("run drop function----") } }
不能手動調(diào)用.drop()方法
但是可以調(diào)用drop(變量)函數(shù) 進(jìn)行手動注銷
Rc引用計(jì)數(shù)智能指針
有時(shí),一個值會有多個所有者
為了支持多重所有權(quán),引入 Rc
Rc只能用于單線程場景
方法:
Rc::clone(&a)函數(shù):增加引用計(jì)數(shù)
Rc::strong_count(&a): 獲得引用計(jì)數(shù)
例子:
enum Node2 { Next2(i32 ,Rc<Node2> ), Nul } use self::Node2::Next2; use self::Node2::Nul; .... main..... let a = Rc::new( Next2(5, Rc::new( Nul ) )); println!("a value is {}",Rc::strong_count(&a)); let b = Rc::new( Next2( 12, Rc::clone(&a) ) ); println!("after b :a value is {}",Rc::strong_count(&a)); let c = Rc::new( Next2( 11, Rc::clone(&a) ) ); println!("after c: a value is {}",Rc::strong_count(&a)); { let d = Rc::new( Next2( 15, Rc::clone(&a) ) ); println!("after d :a value is {}",Rc::strong_count(&a)); } println!("end : a value is {}",Rc::strong_count(&a)); ....end....
通過不可變的引用,使你可以在程序不同部分之間共享只讀數(shù)據(jù)
與clone()相比,屬于淺拷貝,執(zhí)行速度快
RefCell 和內(nèi)部可變性
內(nèi)部可變性:
允許在只持有不可變引用的前提下對數(shù)據(jù)進(jìn)行修改
RefCell 在運(yùn)行時(shí)檢查所有權(quán)規(guī)則
只能用于單線程的代碼
Box | Rc | RefCell | |
---|---|---|---|
同一數(shù)據(jù)所有者 | 一個 | 多個 | 一個 |
可變性、借用檢查 | 可變、不可變借用(編譯時(shí)檢查) | 不可變借用(編譯時(shí)檢查) | 可變、不可變借用(運(yùn)行時(shí)檢查) |
正常情況下無法借用一個不可變的可變借用
let a = 10; let b = &mut a;//錯誤
Refcall 的 .borrow_mut()方法:修改不可變引用的值
到此這篇關(guān)于Rust 智能指針的文章就介紹到這了,更多相關(guān)Rust 智能指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談Rust?+=?運(yùn)算符與?MIR?應(yīng)用
這篇文章主要介紹了Rust?+=?運(yùn)算符與?MIR?應(yīng)用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01如何在Rust中處理命令行參數(shù)和環(huán)境變量
在本章節(jié)中, 我們探討了Rust處理命令行參數(shù)的常見的兩種方式和處理環(huán)境變量的兩種常見方式,感興趣的朋友一起看看吧2023-12-12Rust 連接 SQLite 數(shù)據(jù)庫的過程解析
本文通過一個例子給大家介紹了Rust 連接 SQLite 數(shù)據(jù)庫的詳細(xì)過程,我使用rusqlite這個crate,對Rust 連接 SQLite 數(shù)據(jù)庫相關(guān)知識感興趣的朋友跟隨小編一起看看吧2022-01-01rust 如何使用 cargo-nextest 替代 cargo te
cargo-nextest 是新一代的rust測試程序,能夠極大提升測試性能,可以完全替代 cargo test 命令,這篇文章主要介紹了rust 如何使用 cargo-nextest 替代 cargo test,需要的朋友可以參考下2024-05-05Rust捕獲全局panic并記錄進(jìn)程退出日志的方法
本文提供了捕獲全局panic并記錄進(jìn)程退出日志的方法,首先使用 panic::set_hook 注冊異常處理及panic 觸發(fā)異常,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-04-04Rust中的Iterator和IntoIterator介紹及應(yīng)用小結(jié)
Iterator即迭代器,它可以用于對數(shù)據(jù)結(jié)構(gòu)進(jìn)行迭代,被迭代的數(shù)據(jù)結(jié)構(gòu)是可迭代的(iterable),所謂的可迭代就是這個數(shù)據(jù)結(jié)構(gòu)有返回迭代器的方法,這篇文章主要介紹了Rust中的Iterator和IntoIterator介紹及應(yīng)用,需要的朋友可以參考下2023-07-07Go調(diào)用Rust方法及外部函數(shù)接口前置
這篇文章主要為大家介紹了Go調(diào)用Rust方法及外部函數(shù)接口前置示例實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06rust實(shí)現(xiàn)post小程序(完整代碼)
這篇文章主要介紹了rust實(shí)現(xiàn)一個post小程序,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-04-04