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

Rust?中?Deref?Coercion講解

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

0x00 前言

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

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

0x01 Deref Trait

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

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

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

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

Deref Trait 的定義如下:

pub trait Deref {
    type Target: ?Sized;

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

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

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 機制適配。

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

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)部實現(xiàn)了 String 類型的 Deref trait,并且 type Target = &str 。
當(dāng)引用作為函數(shù)或方法的參數(shù)時,Rust 編譯器將隱式執(zhí)行 deref coercion,以找到適配的類型。這樣省去了 *& 的繁瑣操作,但講真對新手確實不友好。下面是一個示例:

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);
}

再看一個有意思的示例:

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)它找不到這個成員方法的時候會自動嘗試使用 deref() 方法后再找該方法,一直遞歸下去。編譯器在&&&str 類型里面找不到 len 方法,就嘗試將它 deref(),變成 &&str 類型,再尋找 len 方法,還是沒找到,那么繼續(xù) deref(),變成 &str,現(xiàn)在找到 len 方法了,于是就調(diào)用這個方法。

0x03 Option 中的 as_deref()

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

參考文檔

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

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

    這篇文章主要給大家介紹了關(guān)于Rust中引用與借用的相關(guān)資料,rust中借用和引用的附帶功效都一樣,就是都有生命周期,文中通過代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Rust具有一定的參考價值,需要的朋友可以參考下
    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進行異常處理(錯誤的分類與傳遞)

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

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

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

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

    Rust中的Trait與Trait Bounds詳解

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

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

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

    解析rust中的struct

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

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

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

最新評論

东宁县| 宁强县| 浮山县| 甘南县| 九江县| 金湖县| 汝城县| 册亨县| 甘孜| 嘉兴市| 三都| 鹰潭市| 临安市| 温泉县| 宜春市| 汪清县| 陆川县| 大庆市| 鄄城县| 息烽县| 丁青县| 宜丰县| 武冈市| 舟山市| 临洮县| 崇阳县| 城步| 翁牛特旗| 鹿泉市| 贺兰县| 弥渡县| 灌阳县| 新晃| 定西市| 渝中区| 内江市| 河北区| 丁青县| 张掖市| 乌审旗| 石景山区|