chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

為什么Borrow和BorrowMut被定義為泛型trait呢?

冬至子 ? 來(lái)源:山川與湖水 ? 作者:山川與湖水 ? 2023-05-22 15:57 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Borrow和BorrowMut trait 是Rust標(biāo)準(zhǔn)庫(kù)std:borrow 模塊中用于處理借用數(shù)據(jù)的trait,通過(guò)實(shí)現(xiàn)Borrow 和BorrowMut trait可以讓一個(gè)類(lèi)型被借用成不同的引用。

1、AsRef VS Borrow 轉(zhuǎn)換與借用

Borrow trait的定義如下:

pub trait Borrow

對(duì)比一下 AsRef:

pub trait AsRef

可以看出AsRef的定義和Borrow的定義十分相像,那么既然有了AsRef trait,為啥還有Borrow trait的存在呢?

AsRef trait用來(lái)表示**類(lèi)型轉(zhuǎn)換, **Borrow trait用來(lái)表示 借用數(shù)據(jù), 在Rust中,為不同的語(yǔ)義不同的使用情況提供不同的類(lèi)型表示是很常見(jiàn)的。

一個(gè)類(lèi)型通過(guò)實(shí)現(xiàn) Borrow trait,在 borrow()方法中提供對(duì) T 的引用/借用,表達(dá)的語(yǔ)義是可以作為某個(gè)類(lèi)型 T被借用,而非轉(zhuǎn)換。一個(gè)類(lèi)型可以自由地借用為幾個(gè)不同的類(lèi)型,也可以用可變的方式借用。

Borrow trait這類(lèi)特性存在的意義旨在于解決特定領(lǐng)域的問(wèn)題,例如在 Hashset,HashMap,BTreeSet,BtreeMap 中使用 &str 查詢(xún) String 類(lèi)型的鍵。

所以 Borrow 和 AsRef 如何選呢?

  • 當(dāng)你想把不同類(lèi)型的借用進(jìn)行統(tǒng)一抽象,或者當(dāng)你要建立一個(gè)數(shù)據(jù)結(jié)構(gòu),以同等方式處理自擁有值(ownered)和借用值(borrowed)時(shí),例如散列(hash)和比較(compare)時(shí),選擇Borrow。
  • 當(dāng)你想把某個(gè)類(lèi)型直接轉(zhuǎn)換為引用,并且你正在編寫(xiě)通用代碼時(shí),選擇AsRef。比較簡(jiǎn)單的情況。

2、Borrow 和 BorrowMut 實(shí)現(xiàn)借用數(shù)據(jù)

BorrowMut trait的定義如下:

pub trait BorrowMut

BorrowMut trait類(lèi)似于Borrow,用于可變借用。BorrowMut trait繼承自Borrowed trait。因此,一個(gè)類(lèi)型如果實(shí)現(xiàn)了BorrowMut trait,則它也實(shí)現(xiàn)了Borrowed trait。

從Borrow trait的文檔中看,它對(duì)類(lèi)型實(shí)現(xiàn)借用數(shù)據(jù)強(qiáng)加了更多的限制:

如果一個(gè)類(lèi)型U實(shí)現(xiàn)了Borrow,在為U實(shí)現(xiàn)額外的trait(特別是實(shí)現(xiàn)Eq, Ord, Hash)的時(shí)候應(yīng)該實(shí)現(xiàn)與T相同的行為。

這句話可以從例子理解,例如String實(shí)現(xiàn)了Borrow,那么在為String實(shí)現(xiàn)Eq, Ord, Hash等trait時(shí),實(shí)現(xiàn)的行為應(yīng)該與str實(shí)現(xiàn)相同。

Borrow trait的文檔中給了一個(gè)HashMap的例子,HashMap利用了String實(shí)現(xiàn)Borrow時(shí),String和str對(duì)Eq, Hash的實(shí)現(xiàn)是相同的這一點(diǎn),可以讓我們可以使用&str作為Key來(lái)訪問(wèn)一個(gè)HashMap。HashMap的定義如下:

use std::borrow::Borrow;
use std:#:Hash;

pub struct HashMap

可以看到get方法的參數(shù)k類(lèi)型是&Q,而不是&K。Q的trait bound是Hash + Eq + ?Sized,而K的trait bound是Borrow。這里K實(shí)現(xiàn)了Borrow, Hash, Eq等作為額外的trait,Borrow trait約定的限制是K和Q對(duì)這些額外trait的實(shí)現(xiàn)行為是相同的。

上面例子說(shuō)明在寫(xiě)通用的代碼時(shí),如果依賴(lài)了Hash, Eq等這些額外的trait的相同的行為,會(huì)使用Borrow trait。這些trait作為trait bounds出現(xiàn)。

再看一個(gè)例子:

// 這個(gè)結(jié)構(gòu)體能不能作為 HashMap 的 key?
pub struct CaseInsensitiveString(String);


// 它實(shí)現(xiàn) Eq 沒(méi)有問(wèn)題
impl PartialEq for CaseInsensitiveString {
    fn eq(&self, other: &Self) -> bool {
       // 但這里比較是要求忽略了 ascii 大小寫(xiě)
        self.0.eq_ignore_ascii_case(&other.0)
    }
}


impl Eq for CaseInsensitiveString { }
// 實(shí)現(xiàn) Hash 沒(méi)有問(wèn)題
// 但因?yàn)?eq 忽略大小寫(xiě),那么 hash 計(jì)算也必須忽略大小寫(xiě)
impl Hash for CaseInsensitiveString {
    fn hash

但是 CaseInsensitiveString 可以實(shí)現(xiàn) Borrow嗎?

很顯然,CaseInsensitiveString 和 str 對(duì) Hash 的實(shí)現(xiàn)不同,str 是不會(huì)忽略大小寫(xiě)的。因此,CaseInsensitiveString不能實(shí)現(xiàn)Borrow,所以 CaseInsensitiveString 不能作為 HashMap 的 key,編譯器就可以通過(guò) Borrow trait 來(lái)識(shí)別這種情況了。但是 CaseInsensitiveString 完全可以實(shí)現(xiàn) AsRef 。這就是 Borrow 和 AsRef 的區(qū)別,Borrow 更加嚴(yán)格一些,并且表示的語(yǔ)義和 AsRef 完全不同。

3、Borrow和BorrowMut的blanket implement

對(duì)于BorrowBorrowMut,Rust為泛型T和&T自動(dòng)實(shí)現(xiàn)了這兩個(gè)trait。

#[stable(feature = "rust1", since = "1.0.0")]
impl

4. 為什么Borrow和BorrowMut被定義為泛型trait

被定義為泛型trait,這樣就可以讓同一個(gè)類(lèi)型同時(shí)有多個(gè)Borrow和BorrowMut trait的實(shí)現(xiàn), 這樣這個(gè)類(lèi)型就可以同時(shí)讓多個(gè)不同的引用類(lèi)型作為它的借用。

例2:

fn main() {
    let s = String::from("hello");
    let s1: &str = s.borrow();
    let s2: &String = s.borrow();
    println!("s1: {s1:p}, s2: {s2:p}"); // s1: 0x7ff58ec05bc0, s2: 0x7ffee9169fe0
}

例2中引用類(lèi)型&str&String都可以作為String類(lèi)型的借用。即通過(guò)實(shí)現(xiàn)Borrow trait可以讓一個(gè)類(lèi)型被借用成不同的引用。

總結(jié)

Borrow trait是用來(lái)表示 借用數(shù)據(jù) ,一個(gè)類(lèi)型通過(guò)實(shí)現(xiàn) Borrow trait,在 borrow()方法中提供對(duì) T 的引用/借用,表達(dá)的語(yǔ)義是可以作為某個(gè)類(lèi)型 T被借用,而非轉(zhuǎn)換。一個(gè)類(lèi)型可以自由地借用為幾個(gè)不同的類(lèi)型,也可以用可變的方式借用。

1 如果一個(gè)類(lèi)型實(shí)現(xiàn)了Borrow,那么這個(gè)類(lèi)型的borrow方法可以從其借用一個(gè)&T

2 可以將 BorrowBorrowMut視作 AsRefAsMut的嚴(yán)格版本,其返回的引用 &T 具有與 Self 相同的 Eq,Hash 和 Ord 的實(shí)現(xiàn)。

注:理解Borrow trait這類(lèi)特性存在的意義,有助于我們揭開(kāi) HashSet,HashMap,BTreeSet 和 BTreeMap 中某些方法的實(shí)現(xiàn)的神秘面紗。但是在實(shí)際應(yīng)用中,幾乎沒(méi)有什么地方需要我們?nèi)?shí)現(xiàn)這樣的特性,因?yàn)樵匐y找到一個(gè)需要我們對(duì)一個(gè)值再創(chuàng)造一個(gè)“借用”版本的類(lèi)型的場(chǎng)景了。對(duì)于某種類(lèi)型 T ,&T 就能解決 99.9% 的問(wèn)題了,且 T: Borrow 已經(jīng)被一攬子泛型實(shí)現(xiàn)對(duì) T 實(shí)現(xiàn)了,所以我們無(wú)需手動(dòng)實(shí)現(xiàn)它,也無(wú)需去實(shí)現(xiàn)某種的對(duì) U 有 T: Borrow 了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Hash算法
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    7583
  • rust語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    3218
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    詳解Rust的

    所有的編程語(yǔ)言都致力于將重復(fù)的任務(wù)簡(jiǎn)單化,并為此提供各種各樣的工具。在 Rust 中,(generics)就是這樣一種工具,它是具體類(lèi)型或其它屬性的抽象替代。在編寫(xiě)代碼時(shí),我們可以直接描述
    發(fā)表于 11-12 09:08 ?1377次閱讀

    Rust中的From和Into trait的基礎(chǔ)使用方法和進(jìn)階用法

    、可靠和安全的系統(tǒng)級(jí)應(yīng)用的首選語(yǔ)言。 Rust中的From和Into是兩個(gè)重要的trait,它們可以幫助我們進(jìn)行類(lèi)型轉(zhuǎn)換。From trait允許我們從一個(gè)類(lèi)型轉(zhuǎn)換到另一個(gè)類(lèi)型,而Into trait則允許我們將一個(gè)類(lèi)型轉(zhuǎn)換為另
    的頭像 發(fā)表于 09-20 10:55 ?2348次閱讀

    Java的背景和作用

    )只能存儲(chǔ)Object類(lèi)型的對(duì)象,這使得在使用集合時(shí)需要進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換,容易出現(xiàn)類(lèi)型錯(cuò)誤。 的背景:在Java 5版本之前,Java的類(lèi)型是靜態(tài)的,在編譯時(shí)確定,并且在運(yùn)行時(shí)擦除類(lèi)型信息。這種情況下,編譯器無(wú)法對(duì)集合的元素類(lèi)型進(jìn)行驗(yàn)證,因此可能會(huì)導(dǎo)致運(yùn)行時(shí)類(lèi)型錯(cuò)誤。
    的頭像 發(fā)表于 09-20 14:30 ?1547次閱讀
    Java<b class='flag-5'>泛</b><b class='flag-5'>型</b>的背景和作用

    labview連接mongdb問(wèn)題,找到不.NET類(lèi)中的類(lèi)

    有沒(méi)有人用labview連接mongodb數(shù)據(jù)庫(kù)的?已下載mongodb的c#驅(qū)動(dòng),利用labview中的.net控件調(diào)用相關(guān)函數(shù),但是驅(qū)動(dòng)中有部分函數(shù)在類(lèi)中, labview能調(diào)用c#中的
    發(fā)表于 04-08 13:38

    冒泡排序法的實(shí)現(xiàn)

    冒泡排序法的實(shí)現(xiàn),自用筆記!
    發(fā)表于 01-20 07:22

    iOS中關(guān)于的解析

    文章圍繞這五點(diǎn): 1. 是什么 2. 為什么要用 3. 怎么用 4.
    發(fā)表于 09-25 10:01 ?0次下載

    java 編程

    一。 概念的提出(為什么需要)? 首先,我們看下下面這段簡(jiǎn)短的代碼: publicclassGenericTest { publicstaticvoidmain(String[
    發(fā)表于 09-27 11:15 ?0次下載

    聊聊java實(shí)現(xiàn)的原理與好處

    摘要: 和C++以模板來(lái)實(shí)現(xiàn)靜多態(tài)不同,Java基于運(yùn)行時(shí)支持選擇了,兩者的實(shí)現(xiàn)原理大相庭徑。C++可以支持基本類(lèi)型作為模板參數(shù),Java卻只能接受類(lèi)作為參數(shù);Java可以在
    發(fā)表于 09-27 16:50 ?0次下載

    Java的工作原理和案例

    是Java語(yǔ)言一個(gè)非常重要的概念,在Java集合類(lèi)框架中被廣泛應(yīng)用。在介紹之前先看一個(gè)例子。
    的頭像 發(fā)表于 07-01 10:14 ?3044次閱讀

    trait中使用 `async fn`

    trait 中使用?async fn async 工作組很高興地宣布?async fn?現(xiàn)在可以在 nightly 版本的 traits 中使用。在 playground 上有一個(gè)完整的工作示例
    的頭像 發(fā)表于 11-23 15:40 ?1146次閱讀

    rust語(yǔ)言基礎(chǔ)學(xué)習(xí): 智能指針之Cow

    Rust中與借用數(shù)據(jù)相關(guān)的三個(gè)trait: Borrow, BorrowMut和ToOwned。理解了這三個(gè)trait之后,再學(xué)習(xí)Rust中能夠?qū)崿F(xiàn)寫(xiě)時(shí)克隆的智能指針Cow
    的頭像 發(fā)表于 05-22 16:13 ?3606次閱讀

    rust語(yǔ)言基礎(chǔ)學(xué)習(xí): Default trait

    Default trait 顧名思義是默認(rèn)值,即Rust特定類(lèi)型實(shí)現(xiàn) Default 特性時(shí),可以為該類(lèi)型賦予了可選的默認(rèn)值。
    的頭像 發(fā)表于 05-22 16:16 ?1708次閱讀

    實(shí)現(xiàn)Rust Trait類(lèi)型 那么該類(lèi)型的引用也實(shí)現(xiàn)了trait嗎?

    如果你在一個(gè)類(lèi)型上實(shí)現(xiàn)了一個(gè)trait,然后引用了這個(gè)類(lèi)型,那么類(lèi)型的引用也實(shí)現(xiàn)了這個(gè)trait嗎?
    的頭像 發(fā)表于 08-28 15:25 ?1724次閱讀

    C語(yǔ)言是否支持編程?

    C語(yǔ)言是否支持編程?毫無(wú)疑問(wèn),答案是不支持。
    的頭像 發(fā)表于 10-16 10:02 ?1182次閱讀

    鴻蒙語(yǔ)言TypeScript學(xué)習(xí)第18天:【

    (Generics)是一種編程語(yǔ)言特性,允許在定義函數(shù)、類(lèi)、接口等時(shí)使用占位符來(lái)表示類(lèi)型,而不是具體的類(lèi)型。
    的頭像 發(fā)表于 04-16 14:56 ?809次閱讀
    鴻蒙語(yǔ)言TypeScript學(xué)習(xí)第18天:【<b class='flag-5'>泛</b><b class='flag-5'>型</b>】