关于解引用*操作符,谨供参考!

一、主要代码

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;但真正落地时往往会踩到…