当前位置: 首页 > news >正文

【Rust自学】15.3. Deref trait Pt.2:隐式解引用转化与可变性

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
请添加图片描述

15.3.1. 函数和方法的隐式解引用转化(Deref Coercion)

隐式解引用转化(Deref Coercion)是为函数和方法提供的一种便捷特性。

它的原理是:*假如类型T实现了Deref trait,那么Deref Coercion可以把T的引用转化为T经过Deref操作后生成的引用。

当某类型的引用传递给函数或者是方法时,但它的类型与定义的参数类型不匹配,Deref Coercion就会自动发生。编译器会对deref进行一系列的调用,来把它转换为所需的参数类型。这个操作在编译时完成,没有额外的性能开销。

这句话比较绕,看个例子就明白了。我们接着上篇文章的代码来写:

use std::ops::Deref;  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) -> &T {  &self.0  }  
}

这是上篇文章的代码,定义了MyBox元组结构体(元组结构体的介绍详见 5.1. 定义并实例化struct),创建了new函数,并为其实现了Deref trait,所以就可以使用一般的解引用操作来处理MyBox

以下是增添的部分:

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

hello这个函数接收&str,也就是字符串切片类型,然后打印出来。

写主函数看看实际使用:

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

mMyBox<String>类型,&m就是&MyBox<String>,而hello函数接收的是&str,但这么写并不会报错,这是为什么呢?

首先MyBox已经实现了Deref trait,所以Rust可以调用deref方法来把&MyBox<String>转化为&String,这就是刚才讲的那个比较绕的规则。

到这一步还没完,&String类型与&str类型不同,又是怎么转换的呢?因为String类型也实现了Deref trait,而且它的deref实现是返回一个字符串切片&str类型,所以Rust会在&String上使用deref&String转化为&str。最终这个类型就匹配了。

而如果Rust没有Deref Coercion,那么写法会是:

hello(&(*m)[..]);
  • 先使用解引用符号*mMyBox<String>转化为String
  • 加上引用符号&mString转化为&String
  • 通过切片操作 [..],可以获得 String 中的完整内容的引用,并且把其值从&String转化为&str

15.3.2. 解引用于可变性

可以使用DerefMut trait重载可变引用的*运算符。DerefMut相比Deref多了Mut,这是指DerefMut返回的是可变引用&mut T,而Deref返回的是不可变引用&T

在类型和trait满足下列三种情况时,Rust会执行Deref Coercion:

  • T:Deref<Target=U>,允许&T转换为&U
    T实现了Deref trait,而Deref trait下的deref方法的返回类型是&U,那么&T就可以被转化为&U
    举个例子,上文代码例的MyBox类型就实现了Deref trait,其deref方法的返回值是泛型参数&T,所以&MyBox就可以转换为&T

  • T:DerefMut<Target=U>,允许&mut T转换为&mut U
    T实现了DerefMut trait(DerefMut返回的是可变引用&mut T),而DerefMut trait下的deref方法的返回类型是&mut U,那么&mut T就可以被转化为&mut U

  • T:Deref<Target=U>,允许&mut T转化为&U
    Rust可以自动地把一个可变引用转化为不可变引用,但是反过来绝对不行。因为将不可变的引用转化为可变的引用要求引用是唯一的(借用规则中有讲,详见 4.4. 引用与借用)。

相关文章:

【Rust自学】15.3. Deref trait Pt.2:隐式解引用转化与可变性

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 15.3.1. 函数和方法的隐式解引用转化(Deref Coercion) 隐式解引用转化(Deref Coercion)是为函数和方法提供的一种便捷特性。 它的原理是…...

密码强度验证代码解析:C语言实现与细节剖析

在日常的应用开发中&#xff0c;密码强度验证是保障用户账户安全的重要环节。今天&#xff0c;我们就来深入分析一段用C语言编写的密码强度验证代码&#xff0c;看看它是如何实现对密码强度的多维度检测的。 代码整体结构 这段C语言代码主要实现了对输入密码的一系列规则验证&a…...

arkts bridge使用示例

接上一篇&#xff1a;arkui-x跨平台与android java联合开发-CSDN博客 本篇讲前端arkui如何与后端其他平台进行数据交互&#xff0c;接上一篇&#xff0c;后端os平台为Android java。 arkui-x框架提供了一个独特的机制&#xff1a;bridge。 1、前端接口定义实现 定义一个bri…...

LINUX部署微服务项目步骤

项目简介技术栈 主体技术&#xff1a;SpringCloud&#xff0c;SpringBoot&#xff0c;VUE2&#xff0c; 中间件&#xff1a;RabbitMQ、Redis 创建用户 在linux服务器home下创建用户qshh&#xff0c;用于后续本项目需要的环境进行安装配置 #创建用户 useradd 用户名 #设置登录密…...

zsh安装插件

0 zsh不仅在外观上比较美观&#xff0c;而且其具有强大的插件&#xff0c;如果不使用那就亏大了。 官方插件库 https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins 官方插件库并不一定有所有的插件&#xff0c;比如zsh-autosuggestions插件就不再列表里&#xff0c;下面演示zs…...

网站如何正式上线(运维详解)

因为平台原因&#xff0c;不能有太多链接&#xff0c;所以下文中链接都删除了&#xff0c;想访问的去原文链接&#xff1a;https://www.zhoudongqi.com/ TIPS 这篇文章是我自己运营运维的wordpess站点的经验总结&#xff0c;可以说十分详细&#xff0c;域名&#xff0c;服务器和…...

SQL server 数据库使用整理

标题&#xff1a;SQL server 数据库使用整理 1.字符串表名多次查询 2.读取SQL中Json字段中的值&#xff1a;JSON_VALUE&#xff08;最新版本支持&#xff0c;属性名大小写敏感&#xff09; 1.字符串表名多次查询 SELECT ROW_NUMBER() OVER (ORDER BY value ASC) rowid,value…...

【Rust自学】17.2. 使用trait对象来存储不同值的类型

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 17.2.1. 需求 这篇文章以一个例子来介绍如何在Rust中使用trait对象来存储不同值的类型。 …...

初始化mysql报错cannot open shared object file: No such file or directory

报错展示 我在初始化msyql的时候报错&#xff1a;mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory 解读&#xff1a; libaio包的作用是为了支持同步I/O。对于数据库之类的系统特别重要&#xff0c;因此…...

2025年1月22日(网络编程)

系统信息&#xff1a; ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…...

Jason配置环境变量

jason官网 https://jason-lang.github.io/ https://github.com/jason-lang/jason/releases 步骤 安装 Java 21 或更高版本 安装 Visual Studio Code 根据操作系统&#xff0c;请按照以下具体步骤操作 视窗 下载 Jason 的最新版本&#xff0c;选择“jason-bin-3.3.0.zip”…...

蓝桥杯python语言基础(7)——自定义排序和二分查找

目录 一、自定义排序 &#xff08;一&#xff09;sorted &#xff08;二&#xff09;list.sort 二、二分查找 bisect 一、自定义排序 &#xff08;一&#xff09;sorted sorted() 函数会返回一个新的已排序列表&#xff0c;而列表的 sort() 方法会直接在原列表上进行排序…...

(开源)基于Django+Yolov8+Tensorflow的智能鸟类识别平台

1 项目简介&#xff08;开源地址在文章结尾&#xff09; 系统旨在为了帮助鸟类爱好者、学者、动物保护协会等群体更好的了解和保护鸟类动物。用户群体可以通过平台采集野外鸟类的保护动物照片和视频&#xff0c;甄别分类、实况分析鸟类保护动物&#xff0c;与全世界各地的用户&…...

后盾人JS--闭包明明白白

延伸函数环境生命周期 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> <…...

redis的分片集群模式

redis的分片集群模式 1 主从哨兵集群的问题和分片集群特点 主从哨兵集群可应对高并发写和高可用性&#xff0c;但是还有2个问题没有解决&#xff1a; &#xff08;1&#xff09;海量数据存储 &#xff08;2&#xff09;高并发写的问题 使用分片集群可解决&#xff0c;分片集群…...

Kiwi 安卓浏览器本月停止维护,扩展功能迁移至 Edge Canary

IT之家 1 月 25 日消息&#xff0c;科技媒体 Android Authority 今天&#xff08;1 月 25 日&#xff09;发布博文&#xff0c;报道称 Kiwi 安卓浏览器将于本月停止维护&#xff0c;相关扩展支持功能已整合到微软 Edge Canary 浏览器中。 开发者 Arnaud42 表示 Kiwi 安卓浏览器…...

我的AI工具箱Tauri+Django内容生产介绍和使用

在现代内容生产环境中&#xff0c;高效、自动化的工具能够显著提升生产力&#xff0c;降低人工成本。Tauri 与 Django 结合打造的工作箱&#xff0c;集成了强大的 音频处理、视频剪辑、内容下载 以及 AI 文章撰写 等模块&#xff0c;帮助用户在多媒体内容生产的各个环节实现高效…...

四.4 Redis 五大数据类型/结构的详细说明/详细使用( zset 有序集合数据类型详解和使用)

四.4 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; zset 有序集合数据类型详解和使用&#xff09; 文章目录 四.4 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; zset 有序集合数据类型详解和使用&#xff09;1. 有序集合 Zset(sorted set)2. zset 有序…...

Java---猜数字游戏

本篇文章所实现的是Java经典的猜数字游戏 , 运用简单代码来实现基本功能 目录 一.题目要求 二.游戏准备 三.代码实现 一.题目要求 随机生成一个1-100之间的整数(可以自己设置区间&#xff09;&#xff0c;提示用户猜测&#xff0c;猜大提示"猜大了"&#xff0c;…...

网站快速收录:利用RSS订阅提升效率

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/27.html 利用RSS订阅可以显著提升网站内容的更新和收录效率&#xff0c;以下是一些具体的方法和策略&#xff1a; 一、RSS订阅的基本原理 RSS&#xff08;ReallySimpleSyndication或RichS…...

Go语言系统编程与命令行工具

Go语言系统编程与命令行工具 一、命令行参数解析 Go语言提供了多个标准库来处理命令行参数&#xff0c;包括flag包和os包。 使用flag包 package mainimport ("flag""fmt" )func main() {// 定义命令行参数name : flag.String("name", "Gues…...

Task人工智能:如何用Go语言工具构建高效的ML模型训练流水线

Task人工智能&#xff1a;如何用Go语言工具构建高效的ML模型训练流水线 【免费下载链接】task A fast, cross-platform build tool inspired by Make, designed for modern workflows. 项目地址: https://gitcode.com/gh_mirrors/ta/task 在当今的机器学习开发中&#x…...

2026 云手机横评:傲晨云、红手指、川川云、雷电云实测,全能首选一目了然

一、测评背景与说明随着手游挂机、账号多开、云端办公等需求爆发&#xff0c;云手机已成为个人玩家与工作室的必备工具。当前市场品牌繁杂&#xff0c;傲晨云、红手指、川川云、雷电云是关注度较高的四款产品&#xff0c;它们在性能、稳定性、功能及价格上差异显著。本次测评基…...

如何用LRCGET歌词下载神器一键解决数千首离线音乐歌词同步难题

如何用LRCGET歌词下载神器一键解决数千首离线音乐歌词同步难题 【免费下载链接】lrcget Utility for mass-downloading LRC synced lyrics for your offline music library. 项目地址: https://gitcode.com/gh_mirrors/lr/lrcget 你是否拥有一个庞大的离线音乐库&#x…...

Postman数据迁移实战:如何用导入导出功能,在团队间高效同步你的接口集合和环境变量

Postman团队协作指南&#xff1a;接口资产迁移与标准化管理实践 在分布式团队和敏捷开发成为主流的今天&#xff0c;API开发工具的高效使用直接影响着协作效率。作为被全球超过2000万开发者使用的API工具&#xff0c;Postman的集合与环境变量功能已经成为团队间接口定义传递的事…...

深度解析RPG资源解密:Java-RPG-Maker-MV-Decrypter的3大核心技术揭秘

深度解析RPG资源解密&#xff1a;Java-RPG-Maker-MV-Decrypter的3大核心技术揭秘 【免费下载链接】Java-RPG-Maker-MV-Decrypter You can decrypt whole RPG-Maker MV Directories with this Program, it also has a GUI. 项目地址: https://gitcode.com/gh_mirrors/ja/Java-…...

Acton工厂模式:批量部署智能合约的终极技术指南

Acton工厂模式&#xff1a;批量部署智能合约的终极技术指南 【免费下载链接】acton Toolchain for TON smart contract development and beyond 项目地址: https://gitcode.com/GitHub_Trending/acto/acton Acton作为TON区块链智能合约开发的完整工具链&#xff0c;为开…...

舞蹈学论文降AI工具免费推荐:2026年舞蹈学研究毕业论文知网维普99.26%亲测达标4.8元完整方案

舞蹈学论文降AI工具免费推荐&#xff1a;2026年舞蹈学研究毕业论文知网维普99.26%亲测达标4.8元完整方案 直接给结论&#xff1a;嘎嘎降AI&#xff08;www.aigcleaner.com&#xff09;&#xff0c;4.8元&#xff0c;知网AI率55%降到5.3%&#xff0c;稳定可靠。 舞蹈学论文降A…...

FanControl完全指南:Windows风扇智能控制的终极解决方案

FanControl完全指南&#xff1a;Windows风扇智能控制的终极解决方案 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/…...

基于物联网节能及安防控制系统(有完整资料)

编号&#xff1a;CJ-32-2022-153设计简介&#xff1a;本设计是基于物联网节能及安防控制系统&#xff0c;主要实现以下功能&#xff1a;1、检测光强&#xff0c;室内外温度&#xff08;两个温度传感器&#xff09;&#xff0c;人体红外检测是否有人&#xff1b; 2、室外温度过高…...