Rust : 關于解引用“*”

關于解引用*操作符,謹供參考!

一、主要代碼

use std::ops::Deref;
fn main() {model_1();model_2();model_3();model_4();model_5();model_6();model_7();model_8();model_9();
}

二、*操作符與常見的引用和解引用

fn model_1(){let reference:&String = &String::from("hello");match *reference {// val :&Stringref val => println!("通過解引用和重新借用獲得的值: {:?}", val),}
}

如果沒有ref會如何?自行試一下,便知。

三、*操作符與match和Deref的簡單組合

fn model_2(){model_2_1();model_2_2();model_2_3();fn model_2_1(){let mybox = MyBox::new(String::from("hello world"));//*mybox: String */match *mybox {ref val => println!("通過解引用和重新借用獲得的值: {:?}", val),}println!("mybox:{:?}",mybox);}// 為什么這里不能是&MyBox(val),只能是MyBox(val)? 感覺類型不匹配呀!fn model_2_2(){let mybox = MyBox::new(String::from("hello world"));let ref_mybox = &mybox;// ref_mybox: &MyBox<String>match ref_mybox {//val:&StringMyBox(val) => println!("通過解引用和重新借用獲得的值: {:?}", val),// error//&MyBox(val) => println!("通過解引用和重新借用獲得的值: {:?}", val),}}// 解引用的找開方式fn model_2_3(){let value = MyBox::new(String::from("hello world"));model_2_3_1(&value);fn model_2_3_1(value : &MyBox<String>){match *value {//val: &MyBox<String>ref val=> println!("通過解引用和重新借用獲得的值: {:?}", val),// error//&MyBox(val) => println!("通過解引用和重新借用獲得的值: {:?}", val),// error//MyBox(val) => println!("通過解引用和重新借用獲得的值: {:?}", val),}}}use std::ops::Deref;#[derive(Debug)]struct MyBox<T>(T);impl<T> Deref for MyBox<T> {type Target = T;fn deref(&self) -> &Self::Target {&self.0}}impl<T: std::fmt::Debug> MyBox<T> {fn new(x: T) -> MyBox<T> {MyBox(x)}fn my_print(&self) {match self {MyBox(x) => println!("{:?}", x),}}}
}

四、*操作: move 所有權的情況

需要注意的是,*操作可能會move所有權,需要慎重。當然也有一些特別情況。后面會具體補充說明。

fn model_3(){let vec = vec![1, 2, 3];let v_tmp = &vec; // v_tmp:只是借引用,沒有解引用(轉移所有權)的權力//let v_p = *v_tmp;   // 去掉注釋將報錯,error: 轉移所有權println!("vec:{:?}", v_tmp);
}
// *操作: move 所有權
fn model_4(){let raw = Box::new(String::from("hello world"));let tmp = *raw; // tmp: String//println!("raw:{:?}", raw); // 去掉注釋將報錯,error: 此時raw is moved!let p = &tmp; // p: &Stringprintln!("box:{:?}", p);}
// 請問一下:MyBox為什么不可以和Box一樣操作?
fn model_5(){model_5_1();model_5_2();fn model_5_1(){let raw = MyBox::new(String::from("hello world"));// 下面注釋代碼一起取消將報錯:error//let tmp = *raw; //let p = &tmp;//println!("box:{:?}", p);let p = &*raw; // p: &String ;此時和分開操作不一樣println!("p:{:?}",p);}fn model_5_2(){let value = String::from("hello world"); let raw = MyBox::new(&value); //raw:MyBox<&String>let tmp = *raw; // tmp: &Stringlet p = &**tmp; //p:&strprintln!("box:{:?}", p);}struct MyBox<T>(T);impl<T> MyBox<T> {fn new(x: T) -> MyBox<T> {MyBox(x)}}impl <T> Deref for MyBox<T> {type Target = T;fn deref(&self) -> &Self::Target {&self.0}}
}

五、 *操作符用于賦值

fn model_6(){let mut p = String::from("hello world");//非 copy 類型let mut_p = &mut p; // mut_p: &mut String *mut_p = String::from("Hello World");println!("mut_p:{:?}", mut_p);
}

六、*操作符與match搭配的復雜情況

1、match與字段進行ref 或ref mut組合搭配

這種情況,不會move所有權。

fn model_7(){println!("下面是源碼,謹供參考!")//https://doc.rust-lang.org/src/alloc/borrow.rs.html// impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {//     fn clone(&self) -> Self {//         match *self {//             Borrowed(b) => Borrowed(b),//             Owned(ref o) => {//                 let b: &B = o.borrow();//                 Owned(b.to_owned())//             }//         }//     }// }
}

2、match與"_"搭配

“_”和ref等一樣,是個特別的符號。不會move所有權。

fn model_8(){println!("下面是源碼,謹供參考!");// *self: 為什么可以直接解引用?*self: 字段中沒有ref,但有“_”,也可以//https://doc.rust-lang.org/src/alloc/borrow.rs.html// impl<B: ?Sized + ToOwned> Cow<'_, B> {//     pub const fn is_borrowed(&self) -> bool {//         match *self {//             Borrowed(_) => true,//             Owned(_) => false,//         }//     }//     pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {//         match *self {//             Borrowed(borrowed) => {//                 *self = Owned(borrowed.to_owned());//                 match *self {//                     Borrowed(..) => unreachable!(),//                     Owned(ref mut owned) => owned,//                 }//             }//             Owned(ref mut owned) => owned,//         }//     }// }   }fn model_9(){use std::borrow::Borrow;use std::ops::Deref;let dog = Dog::Borrowed("hello world");model_9_1(&dog);model_9_2(&dog);// *dog: 字段中沒有ref,但有“_”,也可以fn model_9_1(dog: &Dog<'_,str>){match *dog{Dog::Borrowed(_) => {println!("A");}Dog::Owned(_) => {println!("B");}}}// 少了ref,將報錯!fn model_9_2(dog: &Dog<'_,str>){match *dog{Dog::Borrowed(_) => {println!("A");}Dog::Owned(ref own) => {println!("B :{:?}",own);}}}// 模仿Cowenum Dog<'a,B:?Sized+'a> where B: ToOwned{Borrowed(&'a B),Owned( <B as ToOwned>::Owned),}impl<B: ?Sized + ToOwned> Deref for Dog<'_, B> where B::Owned: Borrow<B>,{type Target = B;fn deref(&self) -> &B {match *self {Dog::Borrowed(borrowed) => borrowed,Dog::Owned(ref owned) => owned.borrow(),}}}
}

七、問題

1、類型匹配

在model_2_2()中,為什么這里不能是&MyBox(val),只能是MyBox(val)?

fn model_2_2(){let mybox = MyBox::new(String::from("hello world"));let ref_mybox = &mybox;// ref_mybox: &MyBox<String>match ref_mybox {//val:&StringMyBox(val) => println!("通過解引用和重新借用獲得的值: {:?}", val),// error//&MyBox(val) => println!("通過解引用和重新借用獲得的值: {:?}", val),}
}

為什么上面會用MyBox(val)和匹配&MyBox< String>?思考一下。

2、Box和MyBox的操作的差異

具體在model_4和model_5中。Box可以進行先*后&的分開操作,而MyBox不可以。
具體的不同在于Box中是Unique< T>,而不是和MyBox中T 。

    // 說明:Box源碼如下:  // pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/100346.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/100346.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/100346.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【高級終端Termux】在安卓手機/平板上使用Termux 搭建 Debian 環境并運行 PC 級 Linux 應用教程(含安裝WPS,VS Code)

Termux 搭建 Debian 環境并運行 PC 級 Linux 應用教程 一、前言 1. 背景 眾所周知&#xff0c;最新搭載澎湃OS和鴻蒙OS的平板都內置了PC級WPS&#xff0c;辦公效率直接拉滿&#xff08;板子終于從“泡面蓋”升級為“生產力”了&#xff09;。但問題來了&#xff1a;如果不是這…

從循環到矩陣運算:矢量化加速機器學習的秘訣

矢量化實現全解析&#xff1a;從原理到實戰 在學習數據科學、機器學習和深度學習的過程中&#xff0c;我們經常會聽到一個高頻詞——矢量化&#xff08;Vectorization&#xff09;。很多庫的官方文檔、教程里也不斷強調“要盡量使用矢量化操作&#xff0c;而不是顯式循環”。那…

大數據畢業設計-大數據-基于大數據的熱門游戲推薦與可視化系統(高分計算機畢業設計選題·定制開發·真正大數據)

&#x1f34a;作者&#xff1a;計算機編程-吉哥 &#x1f34a;簡介&#xff1a;專業從事JavaWeb程序開發&#xff0c;微信小程序開發&#xff0c;定制化項目、 源碼、代碼講解、文檔撰寫、ppt制作。做自己喜歡的事&#xff0c;生活就是快樂的。 &#x1f34a;心愿&#xff1a;點…

從零到一:用 Qt + libmodbus 做一個**靠譜**的 Modbus RTU 小工具(實戰總結)

文章目錄從零到一&#xff1a;用 Qt libmodbus 做一個**靠譜**的 Modbus RTU 小工具&#xff08;實戰總結&#xff09;你會得到什么快速背景&#xff1a;為什么是 Modbus RTU&#xff1f;協議速查&#xff08;夠用不啰嗦&#xff09;工程結構與 UI 組織連接“三板斧”&#xf…

使用Python創建本地Http服務實現與外部系統數據對接

在Python 3.10中創建一個能夠處理GET和POST請求的本地HTTP服務器&#xff0c;并提供一個默認的 index.html 頁面是完全可行的。Python的標準庫中的 http.server 模塊雖然簡單&#xff0c;但通過一些自定義擴展可以滿足這個需求。 下面我將提供一個實現方案&#xff0c;它包含一…

了解篇 | StarRocks 是個什么數據庫?

今天簡要介紹一下StarRocks 這個強大的數據庫。注意&#xff1a;本文章內容僅供個人學習&#xff0c;不包含任何推薦性質。StarRocks&#xff08;原名 Doris&#xff09;是一個高性能、全場景的MPP&#xff08;大規模并行處理&#xff09;分析型數據庫。它專為極速的多維聯機分…

SSL部署完成,https顯示連接不安全如何處理?

在部署 SSL 后&#xff0c;如果瀏覽器仍然顯示 “連接不安全” 或 “Not Secure”&#xff0c;通常是由以下幾種原因導致的。針對每種可能的原因和問題&#xff0c;以下提供了詳細的排查和解決方案。 1. 排查問題的可能原因 1.1 SSL 證書未正確安裝 如果 SSL 證書安裝不完整或…

LeetCode熱題100--105. 從前序與中序遍歷序列構造二叉樹--中等

1. 題目 給定兩個整數數組 preorder 和 inorder &#xff0c;其中 preorder 是二叉樹的先序遍歷&#xff0c; inorder 是同一棵樹的中序遍歷&#xff0c;請構造二叉樹并返回其根節點。 示例 1: 輸入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 輸出: [3,9,20,null,n…

【WitSystem】詳解JWT在系統登錄過程中前端做了什么事,后端又做了什么事?

要理解 JWT&#xff08;JSON Web Token&#xff09;登錄流程中前端與后端的職責分工&#xff0c;需先明確 JWT 的核心定位&#xff1a;它是一種無狀態的身份認證令牌&#xff0c;用于替代傳統 Session 認證&#xff0c;解決跨服務、跨域登錄的問題。其流程本質是“后端生成令牌…

MongoDB 在線安裝-一鍵安裝腳本(CentOS 7.9)

1. 腳本概述本腳本用于在 CentOS 7.9 系統上在線安裝 MongoDB&#xff0c;自動處理端口占用和重復安裝問題&#xff0c;并創建管理員用戶 test8&#xff0c;密碼 test123。2. 功能停止并關閉防火墻檢查 27017 端口占用并結束進程如果已安裝 MongoDB&#xff0c;卸載重裝配置 Mo…

樹形數據結構之樹狀基礎-算法賽

今天給分享的是一道算法決賽的題目&#xff0c;這道題目的綜合要求比較高&#xff0c;希望大家可以好好理解&#xff0c;同時這道題用到的是樹狀樹形結構的有關知識。可以用這幾天學的相關內容結合起來。問題描述給定兩個長度為 N的排列 A 和 B。若一對二元組下標 (i,j) 滿足以…

Jenkins 構建清理策略:自帶功能 vs Discard Old Build 插件,全場景實操指南

前言&#xff1a;在 Jenkins 持續集成過程中&#xff0c;構建記錄、工作空間、產物包會不斷積累&#xff0c;既占用磁盤空間&#xff0c;也會讓構建歷史變得臃腫。Jenkins 自帶的“丟棄舊的構建”功能和 Discard Old Build 插件&#xff0c;是兩種常見的構建清理方案。本文將詳…

Leetcode | Hot100

文章目錄兩數之和字母異位詞分組最長連續序列移動零盛水最多的容器三數之和接雨水無重復字符的最長子串找到字符串中所有字母異位詞和為 K 的子數組滑動窗口最大值最小覆蓋子串最大子數組和合并區間輪轉數組除自身以外數組的乘積缺失的第一個正數矩陣置零螺旋矩陣旋轉圖像搜索二…

【論文閱讀】Uncertainty Modeling for Out-of-Distribution Generalization (ICLR 2022)

論文題目&#xff1a;Uncertainty Modeling for Out-of-Distribution Generalization 論文來源&#xff1a;ICLR 2022 論文作者&#xff1a; 論文鏈接&#xff1a;https://arxiv.org/pdf/2202.03958 論文源碼&#xff1a;https://github.com/lixiaotong97/DSU ? 一、摘要…

分布式系統單點登錄(SSO)狀態管理深度解析:從Cookie+Session到JWT的演進之路

分布式系統單點登錄(SSO)狀態管理深度解析&#xff1a;從CookieSession到JWT的演進之路作者&#xff1a;默語佬 | CSDN博主 在分布式微服務架構盛行的今天&#xff0c;單點登錄已成為企業級應用的標準配置。本文將深入探討SSO狀態管理的技術演進&#xff0c;從傳統的CookieSess…

從 WPF 到 Avalonia 的遷移系列實戰篇7:EventTrigger 的遷移

從 WPF 到 Avalonia 的遷移系列實戰篇7&#xff1a;EventTrigger 的遷移 在 WPF 中&#xff0c;EventTrigger 是非常常用的功能&#xff0c;它可以讓我們直接在 XAML 中綁定事件與動畫或動作&#xff0c;實現 UI 的交互效果。例如按鈕點擊時旋轉、鼠標懸停時變色等。 然而&…

深圳比斯特|電池組PACK自動化生產線廠家概述

電池組PACK自動化生產線是指用于生產電池模組的一套自動化系統。這類生產線主要用于生產各類電池組&#xff0c;如鋰離子電池組&#xff0c;應用于電動汽車、儲能系統等領域。自動化生產線通過機械設備和計算機控制系統&#xff0c;實現電池組生產過程的自動化和高效率。整條生…

基于librdkafa C++客戶端生產者發送數據失敗問題處理#2

https://blog.csdn.net/qq_42896627/article/details/149025452?fromshareblogdetail&sharetypeblogdetail&sharerId149025452&sharereferPC&sharesourceqq_42896627&sharefromfrom_link 上次我們介紹了認證失敗的問題。這次介紹另一個問題生產者發送失敗…

pg卡死處理

[postgresapm ~]$ ps -ef|grep postgres:|grep -v grep|awk {print $2}|xargs kill -9 鎖&#xff1a; 1 查找鎖表的pid select pid from pg_locks l join pg_class t on l.relation t.oid where t.relkind r and t.relname lockedtable; 2 查找鎖表的語句 select pid, …

Spring Boot 與 Elasticsearch 集成踩坑指南:索引映射、批量寫入與查詢性能

前言Elasticsearch 作為分布式搜索和分析引擎&#xff0c;憑借其高性能、可擴展性和豐富的查詢能力&#xff0c;被廣泛應用于日志分析、全文檢索、電商搜索推薦等場景。 在 Spring Boot 項目中集成 Elasticsearch 已成為很多開發者的日常需求&#xff0c;但真正落地時往往會踩到…