国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Rust】——通過Deref trait將智能指針當作常規(guī)引用處理

這篇具有很好參考價值的文章主要介紹了【Rust】——通過Deref trait將智能指針當作常規(guī)引用處理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??博主現(xiàn)有專欄:

????????????????C51單片機(STC89C516),c語言,c++,離散數(shù)學,算法設計與分析,數(shù)據(jù)結(jié)構(gòu),Python,Java基礎,MySQL,linux,基于HTML5的網(wǎng)頁設計及應用,Rust(官方文檔重點總結(jié)),jQuery,前端vue.js,Javaweb開發(fā),Python機器學習等
??主頁鏈接:

????????????????Y小夜-CSDN博客

目錄

??追蹤指針的值

??像引用一樣使用Box

??自定義智能指針

??通過實現(xiàn)Deref trait 將某一類型像引用一樣處理

??函數(shù)和方法的隱式Deref強制轉(zhuǎn)換

??Deref強制轉(zhuǎn)換如何與可變交互


????????實現(xiàn)?Deref?trait 允許我們重載?解引用運算符dereference operator*(不要與乘法運算符或通配符相混淆)。通過這種方式實現(xiàn)?Deref?trait 的智能指針可以被當作常規(guī)引用來對待,可以編寫操作引用的代碼并用于智能指針。

????????實現(xiàn)?Deref?trait 允許我們重載?解引用運算符dereference operator*(不要與乘法運算符或通配符相混淆)。通過這種方式實現(xiàn)?Deref?trait 的智能指針可以被當作常規(guī)引用來對待,可以編寫操作引用的代碼并用于智能指針。

??追蹤指針的值

????????常規(guī)引用是一個指針類型,一種理解指針的方式是將其看成指向儲存在其他某處值的箭頭。在示例 15-6 中,創(chuàng)建了一個?i32?值的引用,接著使用解引用運算符來跟蹤所引用的值:

fn main() {
    let x = 5;
    let y = &x;

    assert_eq!(5, x);
    assert_eq!(5, *y);
}

????????變量?x?存放了一個?i32?值?5。y?等于?x?的一個引用??梢詳嘌?x?等于?5。然而,如果希望對?y?的值做出斷言,必須使用?*y?來追蹤引用所指向的值(也就是?解引用),這樣編譯器就可以比較實際的值了。一旦解引用了?y,就可以訪問?y?所指向的整型值并可以與?5?做比較。

??像引用一樣使用Box<T>

fn main() {
    let x = 5;
    let y = Box::new(x);

    assert_eq!(5, x);
    assert_eq!(5, *y);
}

????????將?y?設置為一個指向?x?值拷貝的?Box<T>?實例,而不是指向?x?值的引用。在最后的斷言中,可以使用解引用運算符以?y?為引用時相同的方式追蹤?Box<T>?的指針。接下來讓我們通過實現(xiàn)自己的類型來探索?Box<T>?能這么做有何特殊之處。

??自定義智能指針

????????為了體會默認情況下智能指針與引用的不同,讓我們創(chuàng)建一個類似于標準庫提供的?Box<T>?類型的智能指針。接著學習如何增加使用解引用運算符的功能。

????????從根本上說,Box<T>?被定義為包含一個元素的元組結(jié)構(gòu)體

struct MyBox<T>(T);

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

????????這里定義了一個結(jié)構(gòu)體?MyBox?并聲明了一個泛型參數(shù)?T,因為我們希望其可以存放任何類型的值。MyBox?是一個包含?T?類型元素的元組結(jié)構(gòu)體。MyBox::new?函數(shù)獲取一個?T?類型的參數(shù)并返回一個存放傳入值的?MyBox?實例。

fn main() {
    let x = 5;
    let y = MyBox::new(x);

    assert_eq!(5, x);
    assert_eq!(5, *y);
}

得到的編譯錯誤是:

$ cargo run
   Compiling deref-example v0.1.0 (file:///projects/deref-example)
error[E0614]: type `MyBox<{integer}>` cannot be dereferenced
  --> src/main.rs:14:19
   |
14 |     assert_eq!(5, *y);
   |                   ^^

For more information about this error, try `rustc --explain E0614`.
error: could not compile `deref-example` due to previous error

???MyBox<T>?類型不能解引用,因為我們尚未在該類型實現(xiàn)這個功能。為了啟用?*?運算符的解引用功能,需要實現(xiàn)?Deref?trait。

??通過實現(xiàn)Deref trait 將某一類型像引用一樣處理

????????為了實現(xiàn) trait,需要提供 trait 所需的方法實現(xiàn)。Deref?trait,由標準庫提供,要求實現(xiàn)名為?deref?的方法,其借用?self?并返回一個內(nèi)部數(shù)據(jù)的引用。示例 15-10 包含定義于?MyBox?之上的?Deref?實現(xiàn):

use std::ops::Deref;

impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

type Target = T;?語法定義了用于此 trait 的關(guān)聯(lián)類型。

????????沒有?Deref?trait 的話,編譯器只會解引用?&?引用類型。deref?方法向編譯器提供了獲取任何實現(xiàn)了?Deref?trait 的類型的值,并且調(diào)用這個類型的?deref?方法來獲取一個它知道如何解引用的?&?引用的能力。

*(y.deref())

????????Rust 將?*?運算符替換為先調(diào)用?deref?方法再進行普通解引用的操作,如此我們便不用擔心是否還需手動調(diào)用?deref?方法了。Rust 的這個特性可以讓我們寫出行為一致的代碼,無論是面對的是常規(guī)引用還是實現(xiàn)了?Deref?的類型。

? ?deref?方法返回值的引用,以及?*(y.deref())?括號外邊的普通解引用仍為必須的原因在于所有權(quán)。如果?deref?方法直接返回值而不是值的引用,其值(的所有權(quán))將被移出?self。在這里以及大部分使用解引用運算符的情況下我們并不希望獲取?MyBox<T>?內(nèi)部值的所有權(quán)。

????????注意,每次當我們在代碼中使用?*?時,?*?運算符都被替換成了先調(diào)用?deref?方法再接著使用?*?解引用的操作,且只會發(fā)生一次,不會對?*?操作符無限遞歸替換,解引用出上面?i32?類型的值就停止了,這個值與示例 15-9 中?assert_eq!?的?5?相匹配。

??函數(shù)和方法的隱式Deref強制轉(zhuǎn)換

????????Deref 強制轉(zhuǎn)換deref coercions)將實現(xiàn)了?Deref?trait 的類型的引用轉(zhuǎn)換為另一種類型的引用。例如,Deref 強制轉(zhuǎn)換可以將?&String?轉(zhuǎn)換為?&str,因為?String?實現(xiàn)了?Deref?trait 因此可以返回?&str。Deref 強制轉(zhuǎn)換是 Rust 在函數(shù)或方法傳參上的一種便利操作,并且只能作用于實現(xiàn)了?Deref?trait 的類型。當這種特定類型的引用作為實參傳遞給和形參類型不同的函數(shù)或方法時將自動進行。這時會有一系列的?deref?方法被調(diào)用,把我們提供的類型轉(zhuǎn)換成了參數(shù)所需的類型。

????????Deref 強制轉(zhuǎn)換的加入使得 Rust 程序員編寫函數(shù)和方法調(diào)用時無需增加過多顯式使用?&?和?*?的引用和解引用。這個功能也使得我們可以編寫更多同時作用于引用或智能指針的代碼。

fn hello(name: &str) {
    println!("Hello, {name}!");
}

????????當所涉及到的類型定義了?Deref?trait,Rust 會分析這些類型并使用任意多次?Deref::deref?調(diào)用以獲得匹配參數(shù)的類型。這些解析都發(fā)生在編譯時,所以利用 Deref 強制轉(zhuǎn)換并沒有運行時損耗!

??Deref強制轉(zhuǎn)換如何與可變交互

????????類似于如何使用?Deref?trait 重載不可變引用的?*?運算符,Rust 提供了?DerefMut?trait 用于重載可變引用的?*?運算符。

  • 當?T: Deref<Target=U>?時從?&T?到?&U。
  • 當?T: DerefMut<Target=U>?時從?&mut T?到?&mut U
  • 當?T: Deref<Target=U>?時從?&mut T?到?&U。

????????頭兩個情況除了第二種實現(xiàn)了可變性之外是相同的:第一種情況表明如果有一個?&T,而?T?實現(xiàn)了返回?U?類型的?Deref,則可以直接得到?&U。第二種情況表明對于可變引用也有著相同的行為。

????????第三個情況有些微妙:Rust 也會將可變引用強轉(zhuǎn)為不可變引用。但是反之是?不可能?的:不可變引用永遠也不能強轉(zhuǎn)為可變引用。因為根據(jù)借用規(guī)則,如果有一個可變引用,其必須是這些數(shù)據(jù)的唯一引用(否則程序?qū)o法編譯)。將一個可變引用轉(zhuǎn)換為不可變引用永遠也不會打破借用規(guī)則。將不可變引用轉(zhuǎn)換為可變引用則需要初始的不可變引用是數(shù)據(jù)唯一的不可變引用,而借用規(guī)則無法保證這一點。因此,Rust 無法假設將不可變引用轉(zhuǎn)換為可變引用是可能的。文章來源地址http://www.zghlxwxcb.cn/news/detail-859269.html

到了這里,關(guān)于【Rust】——通過Deref trait將智能指針當作常規(guī)引用處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關(guān)文章

  • C語言指針操作(七)通過指針引用字符串

    C語言指針操作(七)通過指針引用字符串

    通過指針引用字符串詳解,以及字符指針變量和字符數(shù)組的比較、 在平常的案例中已大量地使用了字符串,如在 printf函數(shù)中輸出一個字符串。這些字符串都是以直接形式 (字面形式) 給出的,在一對雙引號中包含若干個合法的字符。在本節(jié)中將介紹使用字符串的更加靈活方便

    2024年02月03日
    瀏覽(23)
  • 8.3 【C語言】通過指針引用數(shù)組

    所謂數(shù)組元素的指針就是數(shù)組元素的地址。 可以用一個指針變量指向一個數(shù)組元素。例如: int a[10]={1,3,5,7,9,11,13,15,17,19}; int *p; p=a[0]; 引用數(shù)組元素可以用下標法,也可以用指針法,即通過指向數(shù)組元素的指針找到所需的元素。 在指針已指向一個數(shù)組元素時,可以對指針進

    2024年02月12日
    瀏覽(22)
  • 8.4 【C語言】通過指針引用字符串

    在C程序中,字符串是存放在字符數(shù)組中的。想引用一個字符串,可以用以下兩種方法。 (1)用字符數(shù)組存放一個字符串,可以通過數(shù)組名和下標引用字符串中一個字符,也可以通過數(shù)組名和格式聲明“%s”輸出該字符串。 例:定義一個字符數(shù)組,在其中存放字符串“I love

    2024年02月11日
    瀏覽(30)
  • 【Rust 基礎篇】Rust Box 智能指針

    在 Rust 中, Box 是一種智能指針類型,用于在堆上分配內(nèi)存并管理其生命周期。 Box 提供了堆分配的功能,并在所有權(quán)轉(zhuǎn)移時負責釋放內(nèi)存。本篇博客將詳細介紹 Rust 中 Box 智能指針的使用方法和相關(guān)概念。 Box 是一個指向堆上分配的值的指針。它提供了所有權(quán)轉(zhuǎn)移和釋放內(nèi)存

    2024年02月16日
    瀏覽(20)
  • C++智能指針學習——小談引用計數(shù)

    C++智能指針學習——小談引用計數(shù)

    目錄 前言 控制塊簡介 共享控制塊 引用計數(shù)與弱引用計數(shù)創(chuàng)建過程 __shared_ptr __shared_count _Sp_counted_base 弱引用計數(shù)增加過程 再談共享控制塊 __weak_count 引用計數(shù)增加過程 弱引用計數(shù)的減少過程 弱引用計數(shù)減為0 引用計數(shù)的減少過程 引用計數(shù)減為0 參考文章 本文結(jié)合源碼討論

    2024年04月08日
    瀏覽(23)
  • rust 智能指針

    Rust中基本數(shù)據(jù)類型(如整數(shù)、浮點數(shù)、布爾值等)通常存儲在棧上。而動態(tài)分配的數(shù)據(jù),如 BoxT 和 VecT 等,存儲在堆上。 Rust 中 Box 是一種智能指針類型,通常用于將值放置在堆上而不是棧上。在 Rust 中,由于所有值的默認生命周期都在當前作用域結(jié)束時結(jié)束,因此在情況需

    2024年02月06日
    瀏覽(18)
  • Rust- 智能指針

    A smart pointer is a data structure that not only acts like a pointer but provides additional functionality. This “smartness” comes from the fact that smart pointers encapsulate additional logical or semantic rules, which are automatically applied to simplify memory or resource management tasks. While different programming languages implement smart point

    2024年02月14日
    瀏覽(20)
  • rust學習-智能指針

    rust學習-智能指針

    示例1 無意義的例子:將一個單獨的值存放在堆上并不是很有意義,b更應該放到棧上 示例2-遞歸類型 一種無法在編譯時知道大小的類型是 遞歸類型(recursive type) 其值的一部分可以是相同類型的另一個值 遞歸類型來源于Lisp語言:cons 函數(shù)(“construct function\\\" 的縮寫)利用兩

    2024年02月16日
    瀏覽(14)
  • 【Rust】Rust學習 第十四章智能指針

    【Rust】Rust學習 第十四章智能指針

    指針 ?( pointer )是一個包含內(nèi)存地址的變量的通用概念。這個地址引用,或 “指向”(points at)一些其他數(shù)據(jù)。Rust 中最常見的指針是第四章介紹的? 引用 ( reference )。引用以? ?符號為標志并借用了他們所指向的值。除了引用數(shù)據(jù)沒有任何其他特殊功能。它們也沒有任

    2024年02月12日
    瀏覽(20)
  • 【Rust】Rust學習 第十五章智能指針

    【Rust】Rust學習 第十五章智能指針

    指針 ?( pointer )是一個包含內(nèi)存地址的變量的通用概念。這個地址引用,或 “指向”(points at)一些其他數(shù)據(jù)。Rust 中最常見的指針是第四章介紹的? 引用 ( reference )。引用以? ?符號為標志并借用了他們所指向的值。除了引用數(shù)據(jù)沒有任何其他特殊功能。它們也沒有任

    2024年02月12日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包