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

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

 更新時間:2023年11月24日 11:57:49   作者:和你一起去月球  
這篇文章主要給大家介紹了關(guān)于Rust中引用與借用的相關(guān)資料,rust中借用和引用的附帶功效都一樣,就是都有生命周期,文中通過代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Rust具有一定的參考價值,需要的朋友可以參考下

1、引用與借用

在之前我們將String 類型的值返回給調(diào)用函數(shù),這樣會導(dǎo)致這個String會被移動到函數(shù)中,這樣在原來的作用域不可訪問了,但是我們功能一個String值得引用,這樣就不會導(dǎo)致這個String類型的值被移動,而傳遞的只是一個引用。引用更像一個指針,因為是一個地址,我們就可以基于這個地址找到改地址上存儲的數(shù)據(jù)。 與指針不同,引用確保指向某個特定類型的有效值。

下面是一個引用傳遞的示例:

fn main() {
    let str = String::from("hello world!");
    let len = _length(&str);
    println!("str is value: {}", str);
    println!("str length is: {}", len)
} 
fn _length(s: &String) ->usize {
    s.len()
}

 運(yùn)行結(jié)果所示所示:

根據(jù)以上代碼可以看出_length方法中傳遞的參數(shù)為&str,所以這里傳遞的是str值的引用,用&符號代表引用

以下是一張對應(yīng)的示意圖:

根據(jù)上圖也能看出s是s1的引用,引用的是s1在堆中對應(yīng)類型的值。

注意:與使用 & 引用相反的操作是 解引用(dereferencing),它使用解引用運(yùn)算符,*。

變量 s 有效的作用域與函數(shù)參數(shù)的作用域一樣,不過當(dāng) s 停止使用時并不丟棄引用指向的數(shù)據(jù),因為 s 并沒有所有權(quán)。當(dāng)函數(shù)使用引用而不是實(shí)際值作為參數(shù),無需返回值來交還所有權(quán),因為就不曾擁有所有權(quán)。

我們將創(chuàng)建一個引用的行為稱為 借用(borrowing),因為我們并沒有擁有它的所有權(quán),只是暫時借用以下。

我們可以嘗試修改一下引用,把引用值改了,看下是否可以,這就類似于我借了別人的東西,然后把東西換了個樣子,看看是不是可以呢?

fn main() {
    let str = String::from("hello world!");
    let len = _length(&str);
    println!("str is value: {}", str);
} 
fn _length(s: &String) {
    s.push_str("我把你給改了..........");
}

運(yùn)行一下,看下結(jié)果:

根據(jù)提示可以s是一個引用,因此它引用的數(shù)據(jù)不能作為可變數(shù)據(jù)借用。

1.1 可變引用

允許我們修改一個借用的值,這就是 可變引用,把上面的示例改一下,如下所示:

fn main() {
    let mut str = String::from("hello world!");
    _length(&mut str);
    println!("str is value: {}", str);
} 
fn _length(s: &mut String) {
    s.push_str("我把你給改了..........");
}

運(yùn)行代碼,再看一下結(jié)果:

 首先定義str必須時可變的,在方法中傳遞參數(shù),也要指定引用為可變引用,因為引用指向的是被引用的地址,所以就會改變原有的值。

注意:可變引用有一個很大的限制:如果你有一個對該變量的可變引用,你就不能再創(chuàng)建對該變量的引用。

 看以下示例:

fn main() {
    let mut str = String::from("hello world!");
    let a = &mut str;
    let b = &mut str;
    println!("a {}, b{}", a, b)
} 

 根據(jù)錯誤提示,可以知道同一時間不能多次借用str作為可變變量。Rust這樣限制是因為可以在編譯時就避免數(shù)據(jù)競爭。數(shù)據(jù)競爭(data race)類似于競態(tài)條件,它可由這三個行為造成:

  • 兩個或更多指針同時訪問同一數(shù)據(jù)。
  • 至少有一個指針被用來寫入數(shù)據(jù)。
  • 沒有同步數(shù)據(jù)訪問的機(jī)制。

再看下以下示例:

fn main() {
    let mut str = String::from("hello world!");
    let c = &mut str;
    let b = &str;
    println!("b{} {}", b, c)
} 

 也會報錯,借用和可變借用不能同時被使用。

 再看下一個示例:

fn main() {
    let mut str = String::from("hello world!");
    let c = &mut str;
   
    println!("{}", c);
    let b = &str;
    println!("{}", b)
} 

 可以看到這次是可以打印處結(jié)果的,在第一次打印的時候,變量的作用域也就結(jié)束了,因而在下次進(jìn)行賦值時可以的。

1.2 懸垂引用

在具有指針的語言中,很容易通過釋放內(nèi)存時保留指向它的指針而錯誤地生成一個 懸垂指針(dangling pointer),所謂懸垂指針是其指向的內(nèi)存可能已經(jīng)被分配給其它持有者。相比之下,在 Rust 中編譯器確保引用永遠(yuǎn)也不會變成懸垂?fàn)顟B(tài):當(dāng)你擁有一些數(shù)據(jù)的引用,編譯器確保數(shù)據(jù)不會在其引用之前離開作用域。

下面時一個懸垂應(yīng)用的示例:

fn main() {
    dp();
} 
fn dp() -> &String {    // 返回字符串的引用
    let str = String::from("hello world!");   // 創(chuàng)建一個字符串
    &str      // 返回字符串的引用
}  // str 的作用域結(jié)束
// 方法返回的時字符串的引用,而字符串離開作用與,被釋放,然在此返回該字符串的引用,
// 就會導(dǎo)致返回的結(jié)果不是預(yù)期的結(jié)果,在Rust中是不讓這樣操作的。

 直接運(yùn)行,會報如下錯誤:

根據(jù)報錯可知,此函數(shù)的返回類型包含借用值,但沒有可供借用的值,在返回類型引用處,提示: 錯誤的聲明周期修飾符。

我們改以下返回字符串本身,看一下結(jié)果怎么樣?

fn main() {
    println!("value is {}", dp())
} 
fn dp() -> String {    
    let str = String::from("hello world!");   
    return str
}  

運(yùn)行一下看看:

發(fā)現(xiàn)對應(yīng)的值給打印出來,所有權(quán)交出去了,所以,可打印出對應(yīng)的值。

1.3 引用的規(guī)則

根據(jù)之前的結(jié)果,我們可以總結(jié)出以下兩點(diǎn):

  • 在任意給定時間,要么 只能有一個可變引用,要么 只能有多個不可變引用。
  • 引用必須總是有效的。

2、slice 類型

 slice 允許你引用集合中一段連續(xù)的元素序列,而不用引用整個集合。slice 是一類引用,所以它沒有所有權(quán)。

以下有個slice示例:

fn main() {
        let s = String::from("hello world");
        let hello = &s[0..5];
        let world = &s[6..11];
        println!("{}---{}", hello, world)  
} 

運(yùn)行以下,看下結(jié)果如何: 

根據(jù)以上結(jié)果,可以知道hello變量從字符串(hello world)中進(jìn)行截取的,開始的位置為0,長度為5,所以打印的結(jié)果為hello,而world變量是從開始索引6開始,11結(jié)束,11-5=6,那么它的長度也是5,所以打印的結(jié)果為world.

Slice 的主要結(jié)果包括2部分:

  • 第一部分,是指針,指向數(shù)據(jù)開始的位置
  • 第二部分,是長度,就是元素結(jié)束減去開始位置的值

以下是一個示意圖,能夠更加清楚知道slice與字符串的關(guān)系:

其他寫法,例如取前5個字符:

fn main() {
        let s = String::from("hello world");
        let hello = &s[0..5];
        let hello1 = &s[..5];  // hello 和 hello1 是等價的
        println!("{}---{}", hello, hello1)  
} 

例如取最后5個字符:

fn main() {
        let s = String::from("hello world");
        let world = &s[6..];
        let world1 = &s[6..];
        println!("{}---{}", world, world1)  
} 

取整個長度的切片:

fn main() {
        let s = String::from("hello world");
        let world = &s[..];
        let world1 = &s[..];
        println!("{}---{}", world, world1)  
} 

注意:字符串 slice range 的索引必須位于有效的字符邊界內(nèi),如果嘗試從超過邊界訪問超出索引范圍將導(dǎo)致panic錯誤。

 2.1 字符串字面量其實(shí)就是一個slice

一個示例如下所示:

這里 s1 的類型是 &str:world 的類型也是&str,所以s1它是一個指向二進(jìn)制程序特定位置的 slice。這也就是為什么字符串字面值是不可變的;&str 是一個不可變引用。

2.2 總結(jié)

所有權(quán)、借用和 slice 這些概念讓 Rust 程序在編譯時確保內(nèi)存安全。Rust 語言提供了跟其他系統(tǒng)編程語言相同的方式來控制你使用的內(nèi)存,但擁有數(shù)據(jù)所有者在離開作用域后自動清除其數(shù)據(jù)的功能意味著你無須額外編寫和調(diào)試相關(guān)的控制代碼。

到此這篇關(guān)于Rust中引用與借用的文章就介紹到這了,更多相關(guān)Rust引用與借用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

    Rust?生命周期機(jī)制是與所有權(quán)機(jī)制同等重要的資源管理機(jī)制,之所以引入這個概念主要是應(yīng)對復(fù)雜類型系統(tǒng)中資源管理的問題,這篇文章主要介紹了Rust指南之生命周期機(jī)制詳解,需要的朋友可以參考下
    2022-10-10
  • Rust 入門之函數(shù)和注釋實(shí)例詳解

    Rust 入門之函數(shù)和注釋實(shí)例詳解

    這篇文章主要為大家介紹了Rust 入門之函數(shù)和注釋實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Rust中向量的學(xué)習(xí)筆記

    Rust中向量的學(xué)習(xí)筆記

    在Rust語言中,向量是一種動態(tài)數(shù)組類型,可以存儲相同類型的元素,并且可以在運(yùn)行時改變大小,本文就來介紹一下Rust中向量,感興趣的可以了解一下
    2024-03-03
  • rust中async/await的使用示例詳解

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

    在Rust中,async/await用于編寫異步代碼,使得異步操作更易于理解和編寫,通過使用await,在async函數(shù)或代碼塊中等待Future完成,而不會阻塞線程,允許同時執(zhí)行其他Future,這種機(jī)制簡化了異步編程的復(fù)雜性,使代碼更加直觀
    2024-10-10
  • RUST異步流處理方法詳細(xì)講解

    RUST異步流處理方法詳細(xì)講解

    這篇文章主要介紹了RUST異步流處理方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • 通過rust實(shí)現(xiàn)自己的web登錄圖片驗證碼功能

    通過rust實(shí)現(xiàn)自己的web登錄圖片驗證碼功能

    本文介紹了如何使用Rust和imagecrate庫生成圖像驗證碼,首先,通過Cargo.toml文件添加image依賴,然后,生成純色圖片并編輯驗證圖片,接著,編寫隨機(jī)函數(shù)獲取字符,并通過循環(huán)生成驗證碼圖片,最終,通過運(yùn)行函數(shù)驗證驗證碼圖片是否生成,感興趣的朋友一起看看吧
    2025-03-03
  • Rust用宏實(shí)現(xiàn)參數(shù)可變的函數(shù)的實(shí)現(xiàn)示例

    Rust用宏實(shí)現(xiàn)參數(shù)可變的函數(shù)的實(shí)現(xiàn)示例

    本文主要介紹了Rust用宏實(shí)現(xiàn)參數(shù)可變的函數(shù)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Rust中多線程?Web?服務(wù)器的項目實(shí)戰(zhàn)

    Rust中多線程?Web?服務(wù)器的項目實(shí)戰(zhàn)

    本文主要介紹了Rust中多線程?Web?服務(wù)器的項目實(shí)戰(zhàn),利用通道和互斥鎖管理任務(wù)隊列,解決單線程處理請求的性能瓶頸,確保并發(fā)處理能力并實(shí)現(xiàn)優(yōu)雅關(guān)閉機(jī)制
    2025-06-06
  • rust交叉編譯問題及報錯解析

    rust交叉編譯問題及報錯解析

    這篇文章主要為大家介紹了rust交叉編譯問題及報錯解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • rust 如何使用文件鎖防止應(yīng)用多開

    rust 如何使用文件鎖防止應(yīng)用多開

    這篇文章主要介紹了rust 如何使用文件鎖防止應(yīng)用多開,本文給出了進(jìn)程只能單開的方法,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-04-04

最新評論

吉安市| 邹平县| 湘潭县| 浦城县| 通江县| 云梦县| 淮阳县| 金堂县| 赤水市| 罗山县| 普兰店市| 扬州市| 红河县| 册亨县| 项城市| 永泰县| 马边| 犍为县| 石狮市| 时尚| 馆陶县| 定日县| 全南县| 大同市| 丹巴县| 通化市| 东安县| 鞍山市| 保靖县| 离岛区| 泸州市| 邯郸市| 吉首市| 金秀| 武定县| 景谷| 临泽县| 寿阳县| 射洪县| 志丹县| 修文县|