玩转Rust高级应用 怎么理解在标准库中,有一个std::intrinsics模块,它里面包含了一系列的编译器内置函数
内置函数在标准库中有一个std::intrinsics模块它里面包含了一系列的编译器内置函 数。这些函数都有一个externrust-intrinsic修饰它们看起来都像一种特殊的 FFI 外部函数大家打开标准库的源代码src/core/intrinsics.rs,可以看到这些函数 根本没有函数体因为它们的实现是在编译器内部而不是在标准库内部。调用它们的时候 都必须使用unsafe 才可以。编译器见到这些函数就知道应该生成什么样的代码而不是像 普通函数调用一样处理。另外intrinsics 是藏在一个feature gate后面的这个feature 可能 永远不会稳定这些函数就不是准备直接提供给用户使用的。一般标准库会在这些函数基础 上做一个更合适的封装给用户使用。下面就在这些函数中挑一部分作介绍。transmutefn transmuteT,U(e:T)-U函数可以执行强制类型转换。把一个T 类型参 数转换为U类型返回值转换过程中这个参数的内部二进制表示不变。但是有一个约束条 件即size_of::()size_of::() 。 如果不符合这个条件会发生编译错误。 transmute_copy的作用跟它类似区别是参数类型是一个借用为T。一般情况下我们也可以用as 做类型转换把T 类型指针转换为裸指针然后再转换为U类型的指针。这样也可以实现类似的功能。但是用户自己实现的泛型函数有一 个缺陷即无法在where 条件中自己表达size_of::()size_of::() 。而 transmute作为一个内置函数就可以实现这样的约束。transmute和 transmute_copy在 std::mem 块中重新导出。用户如果需要请使用这个模块而不是std::intrinsics模块。下面用一个示例演示一下Vec 类型的二进制表示是怎样的fnmain(){letxvec![1,2,3,4,5];unsafe{lett:(usize,usize,usize)std::mem::transmute_copy(x);println!({}{}{},t.0,t.1,t.2);}}上面的例子中我们调用了transmute_copy, 因此参数类型是Vec 。假如我们用 transmute 函数参数类型就必须是Vec, 区别在于参数会被move 进入这个函数中 在后面就不能继续使用了。在调用transmute_copy 函数的时候必须显示指定返回值类型因为它是泛型函数返回值类型可以有多种多样的无穷变化只要满足size_of:: ()size_of::() 条件都可以完成类型转换。所以编译器自己是无法自动推理出 返回值类型的。在上例中我们的返回值类型是包含三个usize 的 tuple类型。这是因为 Vec 中实际包含了3个成员一个是指向堆上的指针一个是指向内存空间的总大小还有 一个是实际使用了的元素个数因此这个类型转换从编译器看来是满足“占用内存空间相同” 这一条件的。编译执行我们就可以看到Vec 内部的具体内存表示了。执行结果为639392055intrinsics模块里面有几个与内存读写相关的函数比如copy 、copy_nonoverla-pping 、write_bytes 、move_val_init 、volatile_load 等。这些函数又在std::ptr/std::mem 模块中做了个简单封装然后暴露出来给用户使用。下面挑其中几个重要 的函数介绍。1.copycopy 的完整签名是unsafe fn copy(src:*const T,dst:mut T,count:usize)。 它做的就是把src 指向的内容复制到dst 中去。它跟C 语言里面的 memmove类似都假设src 和 dst 指向的内容可能有重叠。区别是memmove 的参数是 void类型第三个参数是字节长度而ptr::copy 的指针是带类型的第三个参数是对象的个数。这个模块中还提供了ptr::copy_nonoverlapping 。它 跟C 语言里面的memcpy 很像都假设用户已经保证了src 和 dst 指向的内容不可重叠。所以ptr::copy_nonoverlapping的执行速度比 ptr::copy要快一些。2.write在ptr 模块中write 的签名是unsafe fn write(dst:*mut T,src:T), 作用是把变量src 写入到dst 所指向的内存中。注意它的参数src 是使用的类型T, 执行 的 是move 语义。查看源码可知它是基于intrinsics::move_val_init 实现的。注 意在写的过程中不管dst 指向的内容是什么,都会被直接覆盖掉。而src这个对象也 不会执行析构函数。写内存还有ptr::write_bytes 、ptr::write_unaligned 、ptr::write_vol- atile 等函数。3.read在 ptr 模 块 中 read 的 签 名 是unsafe fn read(src:*const T)-T, 作用是把src 指向的内容当成类型T 返回去。查看它的内部源码可见它就是基于 ptr::copy_nonoverlapping 实现的。读内存还有ptr::read_unaligned 以 及ptr::read_volatile 两个函数大同 小异。以上这些内存读写函数都是不管语义直接操作内存中的字节。所以它们都是用 unsafe 函数。4.swap在 ptr 模块中swap 的签名是unsafe fn swap(x:*mut T,y:*mut T),作 用是把两个指针指向的内容做交换。两个指针所指向的对象都只是被修改而不会被析构。这个函数在mem 模块中又做了一次封装变成了unsafe fn swap(x:mut T, y:mut T)供用户使用。签名中的mut 型引用可以保证这两个指针是当前唯一指向该对 象的指针。某些特殊类型还有自己的swap 成员函数。比如Cell::swap(self,other:Cell)。 这个函数跟其他swap 函数最大的区别在于它的参数只要求共享引用不要 求可变引用。这是因为Cell 本身的特殊性。它具备内部可变性所以这么设计是完全安全 的。我们可以从源码看到它就是简单地调用了ptr::swap。5.drop_in_place在 ptr 模块中drop_in_place 的签名是unsafe fn drop_in_placeT:?Sized (to_drop:*mut T)。它的作用是执行当前指向对象的析构函数如果没有就不执行。6.uninitialized在 mem 模块中uninitialized 的签名是unsafe fn uninitialized()-T。 它是基于intrinsics::uninit 函数实现的。我们知道Rust 编译器要求每个变量必须在 初始化之后再使用如果在某些情况下你确实需要未初始化的变量那么必须使用unsafe 才能做到。注意任何时候读取未初始化变量都是未定义行为请大家不要这么做。即便你 在unsafe代码中创造了未初始化变量也需要自己在逻辑上保证读取这个变量之前先为它 合理地赋过值。另外这个函数有点像std::mem::forget, 调用这个函数不仅不会在程序中增加 代码反而会减少可执行代码。调用forget, 会导致编译器不再插入析构函数调用的代码 调用uninitialized会导致缺少初始化。它们没有任何运行开销。uninitialized函数也还没有稳定它有一些无法克服的缺陷将来标准库会废弃掉 这个函数而使用一个新的类型让用户在unsafe代码中创建未初始化变量。综 合 示 例下面我们用一个示例来演示一下这些unsafe函数的用途以及怎样才能正确调用unsafe 代码。示例很简单就是实现标准库中的内存交换函数std::mem::swap。我们可以确定这个函数的签名是fn swap(x:mut T,y:mut T)。关于泛 型的解释在第21章中有此处略过不提。先试一个最简单的实现fn swapT(x:mutT,y:mutT){letz:T*x;*x*y;*yZ;}编译不通过。因为let z *x;执行的是move 语义编译器不允许我们把x 指向的 内容move 出来这只是一个借用而已。如果允许执行这样的操作会导致原来的借用指针 x 指向非法数据。但是我们知道我们这个函数整体上是可以保证安全的因为我们把x 指 向的内容move 出来之后会用其他的正确数据填回去最终可以保证函数执行完之后 x 和y 都是一个正常的状态。这种时候我们就需要动用unsafe了代码如下fn swapT(x:mutT,y:mutT){unsafe{letmut t:Tmem::uninitialized();ptr::copy_nonoverlapping(*x,mut t,1);ptr::copy_nonoverlapping(*y,x,1);ptr::copy_nonoverlapping(t,y,1);mem::forget();}代码逻辑的意思如下。首先我们依然需要 一个作为中转的局部变量。这个局部变量该怎么初始化呢?其实我 们不希望它执行初始化因为我们只需要这部分内存空间而已它里面的内容马上就会被覆 盖掉做初始化是浪费性能。况且我们也不知道用什么通用的办法初始化 一个泛型类型 它 连Default约束都未必满足。所以我们要用mem::uninitialized函 数 。

相关新闻

学乒乓球不踩坑的几大核心:专业、有资质、教练带训有成绩、场地保障、多部门背书、持久老牌

学乒乓球不踩坑的几大核心:专业、有资质、教练带训有成绩、场地保障、多部门背书、持久老牌

在全民运动的热潮下,乒乓球作为国球,深受大众尤其是青少年的喜爱。然而,选择一家靠谱的乒乓球培训机构并非易事,一不小心就可能踩坑。今天,就以重庆市巴南区来奥莱体育培训有限公司旗下的理想乒乓为例,给大…

2026/7/8 2:29:27 阅读更多 →
二本软件工程专业好就业吗?毕业后能做哪些岗位

二本软件工程专业好就业吗?毕业后能做哪些岗位

最近 2026 届找工作,很多二本软件工程同学最焦虑的不是学不会代码,而是投了 30 份简历 只有 3 个回复。 我自己也是从普通本科一路找实习、改简历、刷项目过来的,身边同学有去外包的,也有进银行科技岗、制造业数字化部门的。 今天…

2026/7/8 2:27:27 阅读更多 →
2026年,揭秘苦荞米背后的绿色生产故事

2026年,揭秘苦荞米背后的绿色生产故事

引言在当今社会,随着人们健康意识的不断提高,天然、健康的食品越来越受到消费者的青睐。苦荞米作为其中的一种,因其富含芦丁(维生素P)、膳食纤维及多种微量元素而备受关注。今天,我们将深入探讨苦荞米背后的…

2026/7/8 2:27:27 阅读更多 →

最新新闻

量化派:构建物理AI通用技术底座,开启“卖能力”产业拐点

量化派:构建物理AI通用技术底座,开启“卖能力”产业拐点

量化派探索物理世界生产力,引领物理AI新趋势大语言模型探索了数字世界的生产力,而物理AI正在重新探索物理世界的生产力。量化派不卖机器人本体,也不卖单一解决方案,而是售卖让机器人理解物理世界的通用能力层——物理世界基础模型…

2026/7/8 3:19:46 阅读更多 →
房地产顾问如何突破单一业务模式转型为家族资产配置顾问?

房地产顾问如何突破单一业务模式转型为家族资产配置顾问?

房产中介的传统业务模式高度依赖单套物业的成交。交易一完成,客户关系往往随之结束。当客户手里积累到第二套、第三套房产,开始考虑跨境持有、子女教育与婚姻资产保护时,单一经纪人的知识储备常常触及天花板。客户的问题从"买哪套房子&q…

2026/7/8 3:19:46 阅读更多 →
计网-如何理解冲突域和广播域

计网-如何理解冲突域和广播域

如何理解冲突域和广播域 1. 冲突域 (Collision Domain) 核心定义: 在一个网络中,如果两台设备同时发送数据会导致信号在物理介质上发生碰撞(冲突),那么这些设备就处于同一个冲突域。 通俗理解: 想象一条单车…

2026/7/8 3:17:45 阅读更多 →
不是接口调不通,而是链路没拆清:Dify RAG、向量引擎与 timeout 排查实战

不是接口调不通,而是链路没拆清:Dify RAG、向量引擎与 timeout 排查实战

很多人第一次把 Dify 接进业务系统时,问题通常会被问得很直接:Dify 用什么 API 接口? 如果只是跑通一个简单 Demo,这个问题并不复杂。聊天应用调用聊天消息接口,工作流应用调用工作流运行接口,知识库管理调…

2026/7/8 3:15:45 阅读更多 →
2026无线充赛道洗牌!Qi认证才是品牌合规底气与终端成交利器

2026无线充赛道洗牌!Qi认证才是品牌合规底气与终端成交利器

01 Qi认证,是无线充行业的硬性准入壁垒很多从业者误以为无线充入行门槛低、随便贴牌就能卖,实则不然。WPC无线充电联盟对Qi认证有着极其严苛的审核标准,绝非普通质检证书可比:✅ 品牌资质、工厂品控、生产线合规全方位审核&#x…

2026/7/8 3:11:44 阅读更多 →
三款热门随身WiFi用了三个月:格行、波导、华为,谁的信号先垮、流量先虚?

三款热门随身WiFi用了三个月:格行、波导、华为,谁的信号先垮、流量先虚?

随身WiFi新机到手,测速数据往往都很漂亮,但真正拉开产品差距的,是长期使用后的真实表现。使用一两个月后,信号是否持续稳定、流量是否偷偷虚标提速、机身发热是否加剧、会不会频繁断流,才是决定日常体验的核心关键。本…

2026/7/8 3:09:44 阅读更多 →

日新闻

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: …

2026/7/8 0:00:48 阅读更多 →
MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N1 到批处理的全路径 一、从"功能正确"到"性能可接受"——MyBatis 批量操作的三段式进化 MyBatis 在日常增删改查场景中几乎是无感的——实体映射直观、SQL 控制灵活。但当数据量从千级上升到十万级、百万级,许…

2026/7/8 0:00:48 阅读更多 →
工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

1. 工业负载控制方案概述在工业自动化、电机驱动和照明控制等高需求场景中,可靠地控制电感和电阻负载是核心挑战之一。TPD2015FN作为东芝的8通道高端智能功率开关IC,配合PIC18F45K22微控制器,能够构建一套稳定、高效的负载控制系统。这套组合…

2026/7/8 0:02:48 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/7 14:24:45 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/7 15:59:06 阅读更多 →

月新闻