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

rust智能指針的具體使用

 更新時(shí)間:2023年12月07日 15:00:27   作者:int8  
智能指針是一些數(shù)據(jù)結(jié)構(gòu),它們的行為類(lèi)似于指針但擁有額外的元數(shù)據(jù)和附加功能,本文就來(lái)介紹一下rust智能指針的具體使用,感興趣的可以了解一下

一、智能指針是什么

指針是一個(gè)存儲(chǔ)內(nèi)存地址的變量。這個(gè)地址指向一些其他數(shù)據(jù)。
智能指針是一類(lèi)數(shù)據(jù)結(jié)構(gòu),它們類(lèi)似指針,但是擁有額外的功能。智能指針的概念起源于C++。Rust標(biāo)準(zhǔn)庫(kù)提供了許多智能指針,比如String和Vec<T>,雖然我們并不這么稱(chēng)呼它們,但這些類(lèi)型都屬于智能指針。
智能指針通常使用結(jié)構(gòu)體實(shí)現(xiàn)。智能指針與常規(guī)結(jié)構(gòu)體的區(qū)別在于智能指針實(shí)現(xiàn)了Deref和Drop trait。Deref trait使智能指針表現(xiàn)的像引用一樣,這樣就可以編寫(xiě)既用于引用、又用于智能指針的代碼。Drop trait允許我們自定義智能指針離開(kāi)作用域時(shí)的行為。

在Rust中,引用和智能指針的一個(gè)區(qū)別是引用是一類(lèi)只借用數(shù)據(jù)的指針;智能指針則擁有數(shù)據(jù)的所有權(quán)。

二、最常用的一些智能指針

1.Box<T>,用于在堆上分配
2.Rc<T>,一個(gè)引用計(jì)數(shù)類(lèi)型,其數(shù)據(jù)可以有多個(gè)所有者
3.Ref<T> 和RefMut<T>,通過(guò)RefCell<T> 訪(fǎng)問(wèn)(RefCell<T>是一個(gè)在運(yùn)行時(shí)而不是在編譯時(shí)執(zhí)行借用規(guī)則的類(lèi)型)

(一)Box指針

Box<T>類(lèi)型是一個(gè)智能指針,因?yàn)樗鼘?shí)現(xiàn)了Deref trait和Drop trait。
box把值放在堆上而不是棧上。留在棧上的則是指向堆數(shù)據(jù)的指針。除了數(shù)據(jù)被儲(chǔ)存在堆上而不是棧上之外,box沒(méi)有性能損失。不過(guò)也沒(méi)有很多額外的功能。
1.創(chuàng)建Box
使用new函數(shù)創(chuàng)建
例子

fn main() {
     let var_i32 = 5; // 默認(rèn)數(shù)據(jù)保存在 棧 上
     let b = Box::new(var_i32); // 使用Box后數(shù)據(jù)會(huì)存儲(chǔ)在堆上
     println!("b = {}", b);
}

b離開(kāi)作用域時(shí),它將自動(dòng)釋放。這個(gè)釋放包括b本身(位于棧上)和它所指向的數(shù)據(jù)(位于堆上)。

2.使用box
像使用引用一樣使用box。
使用解引用操作符 * 解引用box

fn main() {
     let x = 5; // 值類(lèi)型數(shù)據(jù)
     let y = Box::new(x); // y是一個(gè)智能指針,指向堆上存儲(chǔ)的數(shù)據(jù)5
     println!("{}",5==x);
     println!("{}",5==*y); // 為了訪(fǎng)問(wèn)y存儲(chǔ)的具體數(shù)據(jù),需要解引用
}
編譯運(yùn)行結(jié)果如下
true
true
直接使用  5 == y  會(huì)返回false

3.使用Box創(chuàng)建遞歸類(lèi)型
Rust需要在編譯時(shí)知道類(lèi)型占用多少空間。一種無(wú)法在編譯時(shí)知道大小的類(lèi)型是遞歸類(lèi)型,其值的一部分可以是自身類(lèi)型的另一個(gè)值。這種嵌套可以是無(wú)限的,所以Rust不知道遞歸類(lèi)型需要多少空間。不過(guò)box有一個(gè)已知的大小,所以通過(guò)在遞歸類(lèi)型定義中插入box,就可以創(chuàng)建遞歸類(lèi)型了。一個(gè)常見(jiàn)遞歸類(lèi)型就是鏈表。
實(shí)例

enum List {
     Cons(i32, List),
     Nil,
}
use crate::List::{Cons, Nil};
fn main() {
     let list = Cons(1, Cons(2, Cons(3, Nil)));//使用這個(gè)list來(lái)儲(chǔ)存1, 2, 3
}

第一個(gè)Cons儲(chǔ)存1和另一個(gè)List值。這個(gè)List是一個(gè)Cons值,此cons儲(chǔ)存2和下一個(gè)List值。這個(gè)list又是一個(gè)cons,儲(chǔ)存3和值為Nil的List。這段代碼編譯錯(cuò)誤。因?yàn)檫@個(gè)類(lèi)型 “有無(wú)限的大小”。
因?yàn)?code>Box<T> 是一個(gè)指針,它的大小是確定的,所以將Box作為Cons的成員,這樣List的大小就確定了。

enum List {
     Cons(i32, Box<List>),
     Nil,
}
use crate::List::{Cons, Nil};
fn main() {
     let list = Cons(1,
         Box::new(Cons(2,
              Box::new(Cons(3,
                  Box::new(Nil))))));
}

三、兩個(gè)特性

(一)Deref Trait

1.Deref是由Rust標(biāo)準(zhǔn)庫(kù)提供的一個(gè)特性。
實(shí)現(xiàn)Deref之后就能把智能指針當(dāng)作引用使用,相當(dāng)于重載解引用運(yùn)算符*。
Deref中包含deref()方法。
deref()方法用于引用self實(shí)例并返回一個(gè)指向內(nèi)部數(shù)據(jù)的指針。

例子

use std::ops::Deref;
struct DerefExample<T> {
     value: T
}
impl<T> Deref for DerefExample<T> {
     type Target = T;
     fn deref(&self) -> &Self::Target {
         &self.value
     }
}
let x = DerefExample { value: 'a' };
assert_eq!('a', *x);

范例

use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> {
     fn new(x:T)-> MyBox<T> {
         MyBox(x)
     }
}
impl<T> Deref for MyBox<T> {
     type Target = T;
     fn deref(&self) -> &T {
         &self.0
     }
}
fn main() {
     let x = 5;
     let y = MyBox::new(x); // 調(diào)用new() 返回創(chuàng)建一個(gè)結(jié)構(gòu)體實(shí)例
     println!("5==x is {}",5==x);
     println!("5==*y is {}",5==*y); // 解引用y
     println!("x==*y is {}",x==*y); // 解引用y
}
編譯運(yùn)行結(jié)果如下
5==x is true
5==*y is true
x==*y is true

每次使用 * 時(shí), * 運(yùn)算符都被替換成先調(diào)用deref方法再使用 * 解引用的操作,且只會(huì)發(fā)生一次,不會(huì)無(wú)限遞歸替換 * 操作符,解引用出i32類(lèi)型的值就停止了

2.DerefMut trait用于重載可變引用的 * 運(yùn)算符

3.Deref隱式轉(zhuǎn)換
Deref隱式轉(zhuǎn)換將實(shí)現(xiàn)了Deref的類(lèi)型的引用轉(zhuǎn)換為另一種類(lèi)型的引用。例如,將&String轉(zhuǎn)換為&str,因?yàn)镾tring實(shí)現(xiàn)了Deref因此可以返回&str。Deref強(qiáng)制轉(zhuǎn)換是Rust在函數(shù)或方法傳參上的一種便利操作,并且只能作用于實(shí)現(xiàn)了Deref的類(lèi)型。當(dāng)這種特定類(lèi)型的引用作為實(shí)參傳遞給和形參類(lèi)型不同的函數(shù)時(shí)將自動(dòng)轉(zhuǎn)換類(lèi)型。這時(shí)會(huì)有一系列的deref方法被調(diào)用,把我們提供的類(lèi)型轉(zhuǎn)換成了形參所需的類(lèi)型。
Deref隱式轉(zhuǎn)換使Rust程序員在調(diào)用函數(shù)時(shí)無(wú)需使用過(guò)多& 和 *。這個(gè)功能方便我們編寫(xiě)同時(shí)作用于引用或智能指針的代碼。

實(shí)例

//還是上面的MyBox<T>
fn hello(name: &str) {
     println!("Hello, {name}!");
}
let m = MyBox::new(String::from("Rust"));
hello(&m);

因?yàn)镈eref隱式轉(zhuǎn)換,使用MyBox<String>的引用作為參數(shù)是可行的。
因?yàn)?code>MyBox<T>實(shí)現(xiàn)了Deref,Rust可以通過(guò)deref將&MyBox<String>變?yōu)?amp;String。而String也實(shí)現(xiàn)了Deref,Rust再次調(diào)用deref將&String變?yōu)?amp;str,這就符合hello函數(shù)的定義了。

如果沒(méi)有Deref強(qiáng)制轉(zhuǎn)換,要把&MyBox<String>類(lèi)型的值傳給hello函數(shù),則不得不編寫(xiě)如下代碼

let m = MyBox::new(String::from("Rust"));
hello(&(*m)[..]);

(*m)MyBox<String>解引用為String,接著&和[..]將String轉(zhuǎn)換成&str。
沒(méi)有Deref強(qiáng)制轉(zhuǎn)換的話(huà),所有這些符號(hào)混在一起將難以讀寫(xiě)和理解。Deref強(qiáng)制轉(zhuǎn)換會(huì)自動(dòng)執(zhí)行這些轉(zhuǎn)換。這些轉(zhuǎn)換發(fā)生在編譯時(shí),所以沒(méi)有運(yùn)行時(shí)損耗!

Deref隱式轉(zhuǎn)換有三種情形:
(1)當(dāng)T實(shí)現(xiàn)Deref Target=U 時(shí)從 &T到 &U。
(2)當(dāng)T實(shí)現(xiàn)DerefMut Target=U 時(shí)從 &mut T到 &mut U。
(3)當(dāng)T實(shí)現(xiàn)Deref Target=U 時(shí)從 &mut T到 &U。
第一種情況表明如果有一個(gè) &T,而T實(shí)現(xiàn)了返回U類(lèi)型的Deref,則可以直接得到 &U。
第二種情況表明可變引用也有著相同的行為。
第三個(gè)情況將可變引用強(qiáng)轉(zhuǎn)為不可變引用。但是反過(guò)來(lái)是不行的,不可變引用永遠(yuǎn)也不能強(qiáng)轉(zhuǎn)為可變引用。
這三種情況下,T類(lèi)型都自動(dòng)實(shí)現(xiàn)了U類(lèi)型的所有方法。

(二)Drop Trait

Rust中的析構(gòu)函數(shù)是由Drop trait提供的drop()方法。
Drop Trait只有一個(gè)方法drop() 。
實(shí)現(xiàn)了Drop特質(zhì)的結(jié)構(gòu)體在離開(kāi)了它的作用域時(shí)會(huì)調(diào)用drop()方法。
例子

use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> {
     fn new(x:T)->MyBox<T>{
         MyBox(x)
     }
}
impl<T> Deref for MyBox<T> {
     type Target = T;
     fn deref(&self) -< &T {
         &self.0
     }
}
impl<T> Drop for MyBox<T>{
     fn drop(&mut self){
         println!("dropping MyBox object from memory ");
     }
}
fn main() {
     let x = 50;
     MyBox::new(x);
     MyBox::new("Hello");
}
編譯運(yùn)行結(jié)果如下
dropping MyBox object from memory
dropping MyBox object from memory

到此這篇關(guān)于rust智能指針的具體使用的文章就介紹到這了,更多相關(guān)rust智能指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust模塊關(guān)鍵詞和哈希表詳解

    Rust模塊關(guān)鍵詞和哈希表詳解

    文章介紹了Rust編程語(yǔ)言中模塊系統(tǒng)、路徑控制、as關(guān)鍵字、外部包的使用以及哈希表的操作,主要涵蓋了如何通過(guò)pub關(guān)鍵字控制模塊和結(jié)構(gòu)體的可見(jiàn)性,文章還詳細(xì)講解了哈希表的創(chuàng)建、訪(fǎng)問(wèn)、所有權(quán)轉(zhuǎn)移、更新操作,感興趣的朋友一起看看吧
    2026-03-03
  • Rust語(yǔ)言和C/C++區(qū)別對(duì)比,Rust和C語(yǔ)言哪個(gè)好

    Rust語(yǔ)言和C/C++區(qū)別對(duì)比,Rust和C語(yǔ)言哪個(gè)好

    Rust具有與C語(yǔ)言相當(dāng)?shù)乃俣群蛢?nèi)存效率,但無(wú)需手動(dòng)內(nèi)存管理或垃圾回收,它擁有出色的工具支持、友好的編譯器和不斷發(fā)展的開(kāi)發(fā)者社區(qū),使用Rust能提升程序性能,最重要的是,對(duì)Python開(kāi)發(fā)者而言,Rust比C語(yǔ)言更容易學(xué)習(xí)
    2025-02-02
  • vscode搭建rust開(kāi)發(fā)環(huán)境的圖文教程

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

    本文主要介紹了vscode搭建rust開(kāi)發(fā)環(huán)境的圖文教程,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 深入了解Rust的生命周期

    深入了解Rust的生命周期

    生命周期指的是引用保持有效的作用域,Rust?的每個(gè)引用都有自己的生命周期。本文將通過(guò)示例和大家詳細(xì)說(shuō)說(shuō)Rust的生命周期,需要的可以參考一下
    2022-11-11
  • rust中async/await的使用示例詳解

    rust中async/await的使用示例詳解

    在Rust中,async/await用于編寫(xiě)異步代碼,使得異步操作更易于理解和編寫(xiě),通過(guò)使用await,在async函數(shù)或代碼塊中等待Future完成,而不會(huì)阻塞線(xiàn)程,允許同時(shí)執(zhí)行其他Future,這種機(jī)制簡(jiǎn)化了異步編程的復(fù)雜性,使代碼更加直觀(guān)
    2024-10-10
  • Rust初體驗(yàn):手把手教你構(gòu)建‘Hello,?World!’

    Rust初體驗(yàn):手把手教你構(gòu)建‘Hello,?World!’

    "準(zhǔn)備好了嗎?一起踏上Rust編程語(yǔ)言的精彩旅程!在這篇「Rust初體驗(yàn)」中,我們將手把手教你構(gòu)建經(jīng)典程序“Hello,?World!”,感受Rust的強(qiáng)大與安全,短短幾行代碼,就能讓你對(duì)這個(gè)系統(tǒng)級(jí)語(yǔ)言的魅力一探究竟!快加入吧,驚喜等你發(fā)現(xiàn)!"
    2024-01-01
  • 深入了解Rust的生命周期

    深入了解Rust的生命周期

    生命周期指的是引用保持有效的作用域,Rust的每個(gè)引用都有自己的生命周期。本文將通過(guò)示例和大家詳細(xì)說(shuō)說(shuō)Rust的生命周期,需要的可以參考一下
    2022-12-12
  • Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解

    Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解

    這篇文章主要為大家介紹了Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Rust 函數(shù)式編程的具體使用

    Rust 函數(shù)式編程的具體使用

    本文主要介紹了Rust 函數(shù)式編程的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • 90%的Rust新手都不知道的3個(gè)實(shí)用開(kāi)發(fā)技巧小結(jié)

    90%的Rust新手都不知道的3個(gè)實(shí)用開(kāi)發(fā)技巧小結(jié)

    Rust是一個(gè)新興的系統(tǒng)級(jí)編程語(yǔ)言,以其獨(dú)特的所有權(quán)系統(tǒng)和借用檢查器而聞名,盡管它被認(rèn)為是一門(mén)相對(duì)較難的語(yǔ)言,但只要掌握了正確的學(xué)習(xí)方法,你會(huì)發(fā)現(xiàn)Rust其實(shí)并不復(fù)雜,這篇文章主要介紹了90%的Rust新手都不知道的3個(gè)實(shí)用開(kāi)發(fā)技巧,需要的朋友可以參考下
    2026-06-06

最新評(píng)論

郧西县| 张家界市| 韶关市| 游戏| 宁波市| 赣州市| 于都县| 闸北区| 双城市| 伊春市| 芮城县| 东乡族自治县| 巴东县| 临泉县| 台中市| 平昌县| 南川市| 鄂伦春自治旗| 迁安市| 梁平县| 孝义市| 织金县| 四子王旗| 阜宁县| 西昌市| 繁峙县| 桂阳县| 马边| 荥阳市| 神池县| 长垣县| 玉屏| 利津县| 喜德县| 微博| 临泉县| 马尔康县| 故城县| 怀宁县| 安陆市| 留坝县|