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

Rust?中?Deref?Coercion講解

 更新時(shí)間:2022年10月26日 10:50:14   作者:aggresss  
Rust 的設(shè)計(jì)理念一向是顯式比隱式好,也就是說所有的行為盡量在代碼中表現(xiàn)出來,這篇文章主要介紹了Rust?中?Deref?Coercion?介紹,需要的朋友可以參考下

0x00 前言

寫這個(gè)文檔的初衷是因?yàn)樵谥形纳鐓^(qū)看到一個(gè)非常不負(fù)責(zé)任的翻譯,將 “implicit deref coercion” 翻譯成 “隱式 deref 強(qiáng)制”,于是覺得有必要記錄一下,以防止后來的新手在這里翻車。
首先需要解釋一下 “coercion” 在編程語言文檔中尤其是涉及到類型轉(zhuǎn)換時(shí)的中文意思。
類型轉(zhuǎn)換 (type conversion) 包括顯式指定被轉(zhuǎn)換到的類型的顯式轉(zhuǎn)換 (explicit conversion) 或稱 cast,以及與之相對的隱式轉(zhuǎn)換 (implicit conversion) 或稱 coercion。因?yàn)榉g不準(zhǔn)等原因,這兩者之間經(jīng)常被混淆。
cast 和 coercion 同時(shí)出現(xiàn)的時(shí)候,中文把前者翻譯成 “顯式類型轉(zhuǎn)換”,后者翻譯成 “隱式類型轉(zhuǎn)換”。

Rust 的設(shè)計(jì)理念一向是顯式比隱式好,也就是說所有的行為盡量在代碼中表現(xiàn)出來。但也是有例外的,例如接下來我們要討論的兩個(gè)話題。

0x01 Deref Trait

Rust 中有一對運(yùn)算符 &*,分別表示對一個(gè)變量的引用和解引用。
例如下面的代碼:

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

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

如果按照 C 語言的思維方式,這兩個(gè)操作符是互補(bǔ)的,即互為逆操作,但在 Rust 中并不適用。當(dāng)一個(gè)類型實(shí)現(xiàn)了 Deref 這個(gè) Trait 后,對該類型顯式執(zhí)行 *y 操作時(shí),Rust 將隱式執(zhí)行 *(y.deref()) 。
如果沒有實(shí)現(xiàn) Deref trait,只有引用類型可以被解引用,而實(shí)現(xiàn)了 Deref trait 后,編譯器將隱式執(zhí)行 deref 決定返回怎樣的引用類型。

Deref Trait 的定義如下:

pub trait Deref {
    type Target: ?Sized;

    fn deref(&self) -> &Self::Target;
}

有一個(gè)很有趣的點(diǎn),雖然是 Deref 操作,但是返回類型卻是一個(gè)引用類型。這個(gè)在官方文檔中給出了解釋:

The reason the deref method returns a reference to a value, and that the plain dereference outside the parentheses in *(y.deref()) is still necessary, is to do with the ownership system. If the deref method returned the value directly instead of a reference to the value, the value would be moved out of self. We don’t want to take ownership of the inner value inside MyBox in this case or in most cases where we use the dereference operator.

主要原因是為了與大多數(shù)場景下的 ownership 機(jī)制適配。

通過了解 Rust 的 Deref Trait 后,我們可以得出結(jié)論:在 Rust 中 *&T&*T 不一定是同一個(gè)類型,例如下面示例:

use std::ops::Deref;

#[derive(Copy, Clone, Debug)]
struct MyBox {
    alpha: i32,
}

impl Deref for MyBox {
    type Target = i32;

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

fn main() {
    let beta = MyBox { alpha: 32 };
    let gamma = &*beta; // &i32
    let delta = *β // Mybox
    println!("{:?}, {:?}", gamma, delta);
}

0x02 Implicit Deref Coercion

Deref coercion converts a reference to a type that implements the Deref trait into a reference to another type.

最初接觸到 Deref coercion 的場景通常是使用 &str 作為參數(shù)的函數(shù),傳入 &String 是可以編譯通過的,習(xí)慣了 Rust 大爺苛刻的編譯器后覺得這不可思議,深入了解后才知道,Rust 內(nèi)部實(shí)現(xiàn)了 String 類型的 Deref trait,并且 type Target = &str 。
當(dāng)引用作為函數(shù)或方法的參數(shù)時(shí),Rust 編譯器將隱式執(zhí)行 deref coercion,以找到適配的類型。這樣省去了 *& 的繁瑣操作,但講真對新手確實(shí)不友好。下面是一個(gè)示例:

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

struct MyBox<T>(T);

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

use std::ops::Deref;

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

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

fn main() {
    let m = MyBox::new(String::from("Rust"));
    hello(&m);
}

再看一個(gè)有意思的示例:

fn main() {
    let s = "Hello, Rust!";
    println!("length: {}", s.len());
    println!("length: {}", (&s).len());
    println!("length: {}", (&&&&&&&&&&&&&s).len());
}

上面的示例是可以編譯通過的,我們?nèi)绻褂?&&&&&&&&&&str 類型來調(diào)用成員方法,也是可以的。原因是 Rust 編譯器的 deref coercion 是遞歸的,當(dāng)它找不到這個(gè)成員方法的時(shí)候會自動(dòng)嘗試使用 deref() 方法后再找該方法,一直遞歸下去。編譯器在&&&str 類型里面找不到 len 方法,就嘗試將它 deref(),變成 &&str 類型,再尋找 len 方法,還是沒找到,那么繼續(xù) deref(),變成 &str,現(xiàn)在找到 len 方法了,于是就調(diào)用這個(gè)方法。

0x03 Option 中的 as_deref()

熟練的使用 Option 可以在 Rust 開發(fā)中節(jié)省很多頭發(fā)。當(dāng)需要將 Option<T> 轉(zhuǎn)化為 Option<&T> 時(shí),我們通常使用 Option.as_ref() 操作,再結(jié)合 map() 方法可以在不轉(zhuǎn)移所有權(quán)的情況下使用 Option 中的變量。當(dāng)看到 Option.as_deref() 操作時(shí),我們首先會望文生義的認(rèn)為是將 Option<&T> 轉(zhuǎn)化為 Option<T>,但理解了前兩節(jié)的內(nèi)容后會懂得 Option.as_deref() 的操作其實(shí)是 Option.as_ref().map(|s| s.deref()) 的簡寫形式,返回的仍然是一個(gè)引用,目的是為了使用 Rust 中的 deref coercion 機(jī)制。

參考文檔

https://doc.rust-lang.org/std/ops/trait.Deref.html
https://doc.rust-lang.org/book/ch15-02-deref.html
https://stackoverflow.com/questions/8857763/what-is-the-difference-between-casting-and-coercing
https://mp.weixin.qq.com/s/G28XE1rfX0nT6zIi86ji0Q
https://blog.csdn.net/weixin_39702559/article/details/112276392
https://blog.csdn.net/JAN6055/article/details/125774473

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

相關(guān)文章

  • 一文掌握Rust編程中的生命周期

    一文掌握Rust編程中的生命周期

    在Rust語言中, 每一個(gè)引用都有其生命周期, 通俗講就是每個(gè)引用在程序執(zhí)行的過程中都有其自身的作用域, 一旦離開其作用域, 其生命周期也宣告結(jié)束, 值不再有效,這篇文章主要介紹了Rust編程中的生命周期,需要的朋友可以參考下
    2023-11-11
  • Rust中的引用與借用舉例詳解

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

    這篇文章主要給大家介紹了關(guān)于Rust中引用與借用的相關(guān)資料,rust中借用和引用的附帶功效都一樣,就是都有生命周期,文中通過代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Rust具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-11-11
  • Rust?use關(guān)鍵字妙用及模塊內(nèi)容拆分方法

    Rust?use關(guān)鍵字妙用及模塊內(nèi)容拆分方法

    這篇文章主要介紹了Rust?use關(guān)鍵字妙用|模塊內(nèi)容拆分,文中還給大家介紹use關(guān)鍵字的習(xí)慣用法,快速引用自定義模塊內(nèi)容或標(biāo)準(zhǔn)庫,以此優(yōu)化代碼書寫,需要的朋友可以參考下
    2022-09-09
  • Rust?編程語言中的所有權(quán)ownership詳解

    Rust?編程語言中的所有權(quán)ownership詳解

    這篇文章主要介紹了Rust?編程語言中的所有權(quán)ownership詳解的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Rust使用kind進(jìn)行異常處理(錯(cuò)誤的分類與傳遞)

    Rust使用kind進(jìn)行異常處理(錯(cuò)誤的分類與傳遞)

    Rust?有一套獨(dú)特的處理異常情況的機(jī)制,它并不像其它語言中的?try?機(jī)制那樣簡單,這篇文章主要介紹了Rust指南錯(cuò)誤的分類與傳遞以及使用kind進(jìn)行異常處理,需要的朋友可以參考下
    2022-09-09
  • Rust中的關(guān)聯(lián)類型總結(jié)

    Rust中的關(guān)聯(lián)類型總結(jié)

    關(guān)聯(lián)類型是定義通用trait的一種機(jī)制。它允許在trait中定義一個(gè)或多個(gè)占位符類型,這些類型將在trait的實(shí)現(xiàn)中具體化。文中有詳細(xì)示例代碼供參考,需要的朋友可以閱讀一下
    2023-05-05
  • Rust中的Trait與Trait Bounds詳解

    Rust中的Trait與Trait Bounds詳解

    Rust中的Trait與TraitBounds通過《西游記》的故事背景進(jìn)行解釋,Trait是一種接口定義機(jī)制,用于描述角色的能力;TraitBounds用于限制函數(shù)或結(jié)構(gòu)體的參數(shù)類型必須實(shí)現(xiàn)某些trait;BlanketImplementations可以為所有實(shí)現(xiàn)了某類trait的類型提供默認(rèn)的trait實(shí)現(xiàn)
    2025-02-02
  • Rust中泛型的學(xué)習(xí)筆記

    Rust中泛型的學(xué)習(xí)筆記

    在Rust語言中,泛型是一種強(qiáng)大的工具,它允許我們編寫可復(fù)用且靈活的代碼,本文主要介紹了Rust中泛型的學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • 解析rust中的struct

    解析rust中的struct

    自定義的數(shù)據(jù)類型,為相關(guān)聯(lián)的值命名,打包成有意義的組合,類似python的dict,但是賦值的時(shí)候可以不按順序,本文給大家介紹下rust中的struct知識,感興趣的朋友一起看看吧
    2022-10-10
  • rust?創(chuàng)建多線程web?server的詳細(xì)過程

    rust?創(chuàng)建多線程web?server的詳細(xì)過程

    web?server?中主要的兩個(gè)協(xié)議是?http?和?tcp,tcp?是底層協(xié)議,http?是構(gòu)建在?tcp?之上的,本篇文章重點(diǎn)給大家介紹rust?創(chuàng)建多線程web?server的詳細(xì)過程,感興趣的朋友跟隨小編一起看看吧
    2023-11-11

最新評論

尉氏县| 新宾| 阳新县| 寻乌县| 玉树县| 东港市| 丹棱县| 林周县| 林芝县| 定州市| 厦门市| 黑龙江省| 合江县| 南岸区| 比如县| 建水县| 道真| 西乌珠穆沁旗| 富锦市| 焉耆| 克什克腾旗| 永清县| 尼玛县| 淄博市| 阿城市| 普兰县| 邛崃市| 丹东市| 新兴县| 荥阳市| 福建省| 嘉义县| 合川市| 栾城县| 沙洋县| 宜黄县| 马尔康县| 南通市| 湟中县| 老河口市| 连江县|