Rust 智能指針實(shí)現(xiàn)方法
Rust 第24節(jié) 智能指針
智能指針的實(shí)現(xiàn)
智能指針通常使用struct實(shí)現(xiàn),
并實(shí)現(xiàn)Deref和Drop這兩個(gè)trait
Deref trait:允許智能指針struct 的實(shí)例像引用一樣使用
Drop triat: 允許你自定義當(dāng)智能指針實(shí)例走出作用域時(shí)的代碼
標(biāo)準(zhǔn)庫(kù)中常見(jiàn)的智能指針
Box<T>:在heap內(nèi)存上分配值 Rc<T>: 啟用多重所有權(quán)的引用技術(shù)類型 Ref<T> RefMut<T> 通過(guò)RefCall<T> 訪問(wèn):在運(yùn)行時(shí)而不是編譯時(shí)強(qiáng)制借用規(guī)則的類型
使用Box 來(lái)指向Heap上的數(shù)據(jù)
他是最簡(jiǎn)單的智能指針
let b = Box::new(5);
println!("b = {}",b);rust 編譯時(shí)需要知道一個(gè)類型所占的空間大小
但是遞歸類型的大小在編譯時(shí)無(wú)法確認(rèn)大小
使用Box可以解決,Box是指針,大小確認(rèn)
Deref Trait
Deref 解引用,我們可以自定義解引用運(yùn)算符*的行為
通過(guò)Deref,智能指針可以像常規(guī)引用一樣來(lái)處理
解引用運(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);自定義一個(gè)元組指針
struct Mypointer<T>(T); //結(jié)構(gòu)體元組,只有一個(gè)成員
//元組結(jié)構(gòu)體相當(dāng)于沒(méi)有成員名字的結(jié)構(gòu)體,通過(guò)索引訪問(wèn)
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,則編譯器會(huì)自動(dòng)調(diào)用Deref方法,對(duì)參數(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)后,可以自定義值離開(kāi)作用域時(shí)發(fā)生的動(dòng)作
要求實(shí)現(xiàn)drop方法
在變量離開(kāi)作用域時(shí),會(huì)自動(dòng)調(diào)用drop方法
例子:
impl<T> Drop for Mypointer<T> {
fn drop(&mut self) {
println!("run drop function----")
}
}不能手動(dòng)調(diào)用.drop()方法
但是可以調(diào)用drop(變量)函數(shù) 進(jìn)行手動(dòng)注銷
Rc引用計(jì)數(shù)智能指針
有時(shí),一個(gè)值會(huì)有多個(gè)所有者
為了支持多重所有權(quán),引入 Rc
Rc只能用于單線程場(chǎng)景
方法:
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....通過(guò)不可變的引用,使你可以在程序不同部分之間共享只讀數(shù)據(jù)
與clone()相比,屬于淺拷貝,執(zhí)行速度快
RefCell 和內(nèi)部可變性
內(nèi)部可變性:
允許在只持有不可變引用的前提下對(duì)數(shù)據(jù)進(jìn)行修改
RefCell 在運(yùn)行時(shí)檢查所有權(quán)規(guī)則
只能用于單線程的代碼
| Box | Rc | RefCell | |
|---|---|---|---|
| 同一數(shù)據(jù)所有者 | 一個(gè) | 多個(gè) | 一個(gè) |
| 可變性、借用檢查 | 可變、不可變借用(編譯時(shí)檢查) | 不可變借用(編譯時(shí)檢查) | 可變、不可變借用(運(yùn)行時(shí)檢查) |
正常情況下無(wú)法借用一個(gè)不可變的可變借用
let a = 10; let b = &mut a;//錯(cuò)誤
Refcall 的 .borrow_mut()方法:修改不可變引用的值
到此這篇關(guān)于Rust 智能指針的文章就介紹到這了,更多相關(guān)Rust 智能指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust中多線程?Web?服務(wù)器的項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了Rust中多線程?Web?服務(wù)器的項(xiàng)目實(shí)戰(zhàn),利用通道和互斥鎖管理任務(wù)隊(duì)列,解決單線程處理請(qǐng)求的性能瓶頸,確保并發(fā)處理能力并實(shí)現(xiàn)優(yōu)雅關(guān)閉機(jī)制2025-06-06
RUST語(yǔ)言函數(shù)的定義與調(diào)用方法
定義一個(gè)RUST函數(shù)使用fn關(guān)鍵字,下面通過(guò)本文給大家介紹RUST語(yǔ)言函數(shù)的定義與調(diào)用方法,感興趣的朋友跟隨小編一起看看吧2024-04-04
Rust?中的?JSON?處理利器serde_json功能詳解
本文介紹Rust中serde_json庫(kù),用于JSON序列化與反序列化,支持復(fù)雜結(jié)構(gòu)及錯(cuò)誤處理,助力高效處理數(shù)據(jù)交換需求,本文給大家詳細(xì)介紹Rust中的JSON處理利器serde_json功能,感興趣的朋友一起看看吧2025-06-06

