【Rust中级教程】1.13. 内存中的类型 Pt.1:对齐(Alignment)、布局(Layout)、`repr`属性

发布时间:2026/7/24 20:42:13

【Rust中级教程】1.13. 内存中的类型 Pt.1:对齐(Alignment)、布局(Layout)、`repr`属性
1.13 内存中的类型 Pt.1对齐(Alignment)、布局(Layout)、repr属性1.13.1. 类型的基本职责每个Rust值都有类型而类型的职责在于告诉你如何解释内存中的比特位(bits)。例如0b10111101这串比特(bits)本身并没有意义但是- 用u8类型来解释就会得到数字189- 用i8类型来解释就会得到数字-67当自定义类型时编译器决定该类型的各部分在内存表示中的位置1.13.2. 对齐(Alignment)对齐(Alignment)决定了类型的字节可以被存储在哪里。而一旦类型的表示被确定之后你可能想在内存上随便找个地方存进去就行这在理论上是可行的。但实际上计算机硬件对给定的类型可以存放的位置是有约束的。最典型的一个例子是指针它指向的是字节(bytes)而不是位(bits)1个字节等于8比特。换言之它并不指向具体的比特。所以如果将某类型的值放在计算机内存中索引为4的位(bits)上那就无法引用它的地址因为指针指向的是字节而不是具体的比特所以就必须对齐字节也就是对齐到8比特。出于这个原因所有的值无论什么类型都必须开始于字节的边界。所有类型必须至少是字节对齐的(byte-aligned)。换言之存放的地址必须是8bits的整数倍。1.13.3. 更严格的对齐规则有一些类型的对齐规则比字节的对齐规则还要严格在CPU和内存系统里内存经常按大于单个byte的块进行访问。例如在64位的CPU上大部分的值是按照8bytes的块进行访问的每个操作都开始于“8bytes对齐”的地址上。这也叫做CPU的字长英文是word sizeCPU当然也有办法处理更小值的读写以及跨越块边界的值。但是我们作为开发者应该尽可能地保证硬件可以操作于它的原生(native)对齐。举个例子如果想读取的i64值它开始于8bytes块的中间那这个时候要读取它就至少需要两次读取。因为i64是8字节而它开始于两个8字节块中间说明它一定横跨了这两个块。所以在读取时引进就得从这两个块读取数据第一个块读取i64的前面部分第二个块读取i64的后面部分然后再把它们合并到一起。这种操作是非常低效的会拖累程序执行的速度所以我们应该尽可能保证硬件可以操作于它的原生对齐。1.13.4. 没对齐的操作CPU访问内存时数据的地址没有按照架构要求的对齐方式进行访问叫做misaligned access。这会导致性能低下和并发问题。很多CPU操作多要求/强烈建议它们的参数是自然对齐的(naturally aligned)。自然对齐值的对齐是匹配他们值的大小的。例如我想加载8字节那么提供的地址就需要8字节对齐。1.13.5. 编译器会尽可能利用对齐基于类型包含的内容编译器通过计算为类型分配一个对齐或者叫给它分配一个对齐方案- 对于内值的值通常对齐到它们的大小。比如说u8按1字节对齐u16按2字节对齐u32按4字节对齐u64按8字节对齐。而复杂类型包含其它类型的类型通常被赋予所含类型的最大对齐。例如某类型含有u8、u16和u32这三个类型的字段那么类型就应该是4字节对齐u32是最大对齐为4字节1.13.6. 布局(Layout)类型的布局(Layout)指的是编译器决定这个类型在内存上如何表示。Rust编译器对于类型如何布局并没有给出多少保证。Rust提供了repr属性(attribute)它可以添加到你类型的定义上来请求特定的类型表示。1.13.7.repr(C)repr属性(attribute)最常见的一个是repr(C)。名字里带个C说明跟C语言有关系。repr(C)布局方式与C/C编译器对同类型的布局兼容。这对于使用FFI外部函数接口英文是Foreign Function Interface与其它语言交互的Rust代码很有用。使用FFI与其它语言交互的时候Rust会生成一个匹配其它语言编译器期望的布局。因为C语言的布局是可预测且不易改变的所以repr(C)在unsafeunsafe Rust详见 【Rust自学】19.1. 摆脱安全性限制的unsafe Rust的上下文是非常有用的。比如说你使用指向该类型的原始指针时或者在两个具有相同字段的类型间进行转换时都可以使用到repr(C)。1.13.8.repr(transparent)repr(transparent)中的transparent是透明的意思它用于 newtype 风格的包装类型并保证外层类型与其唯一的非零大小字段具有相同的布局。若还有其它字段它们必须是零大小类型例如()或PhantomData。这与newtype模式详见【Rust自学】19.5. 高级类型结合起来很好用。我们在这里回顾一下newtype模式利用元组结构体来构建一个新的类型放在本地相当于是薄封装。举个例子你想操作struct A和struct NewA(A)的内存表示使用了repr(transparent)之后两者的内存表示就应该是一样的。不使用的话Rust编译器就没发保证了。1.13.9. 使用repr属性的例子我们来看一个例子代码字段类型的大小默认内存表示填充最终对齐#[repr(C)]struct Foo {tiny: bool,1 bit1 byte 对齐3 bytesnormal: u32,4 bytes4 bytes 对齐(tinynormal)8 bytessmall: u8,1 byte1 byte 对齐7 bytes8 byteslong: u64,8 bytes8 bytes 对齐8 bytesshort: u16,2 bytes2 bytes 对齐6 bytes8 bytes}共 32 bytes这个表展现了 Rust 结构体在#[repr(C)]下的内存对齐和填充- 代码是最左边的这列使用了repr(C)注解。结构体里面有好几个字段Rust编译器首先看tiny字段是bool类型的占1bit内存就会对齐到1字节编译器接着看normal字段是u32类型的占4字节所以对齐到4字节即可。这时候Rust发现tiny字段对齐到的是1字节所以编译器就会填充3字节让tiny字段占4字节由于这个字段刚好占了8字节是4字节的整数倍所以已经对齐了small字段是u8类型占1字节对齐到1字节。由于上面的两个字段已经对齐了所以Rust编译器会根据下文的字节来判断给它填充多少字节。判断到这里Rust编译器还得观望一下。long是u64类型占8字节自然就是8字节对齐。它的字段是8字节及以上。此时我们看tiny和normal组成了8字节对齐long也是8字节对齐Rust明白了现在的情况是应该按8字节对齐。那就只能给small字段填充7个字节补成一个8字节对齐了。short是u16类型占2字节由于现在的情况是应该按8字节对齐所以编译器会给它补6字节合成8字节对齐。其过程用表格表述就是字段类型大小需要的对齐填充情况备注tiny: bool1 bit1 byte3 bytes 填充为了对齐下一个u32normal: u324 bytes4 bytes无填充按u32对齐small: u81 byte1 byte7 bytes 填充为了对齐下一个u64long: u648 bytes8 bytes无填充8 字节对齐short: u162 bytes2 bytes6 bytes 填充以8字节对齐结构体

相关新闻

终极文档下载工具指南:一键免费下载30+文库平台的完整教程

终极文档下载工具指南:一键免费下载30+文库平台的完整教程

2026/7/24 20:42:13

终极文档下载工具指南:一键免费下载30文库平台的完整教程 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为…

没有无限的货币就无法维持无限的上涨。

没有无限的货币就无法维持无限的上涨。

2026/7/24 20:42:13

您的直觉非常敏锐,直接切中了金融市场中最具体、最具有物质约束力的一个核心要素——流动性(货币总量)的物理边界。 在物理学中,没有无限的能量,就无法维持无限的运动;在金融学中,没有无限的货币…

5分钟零门槛搭建你的AI股票分析助手:daily_stock_analysis终极指南

5分钟零门槛搭建你的AI股票分析助手:daily_stock_analysis终极指南

2026/7/24 20:32:13

5分钟零门槛搭建你的AI股票分析助手:daily_stock_analysis终极指南 你是否曾经为复杂的股票分析感到头疼?面对海量的行情数据、技术指标和新闻资讯,普通投资者往往无从下手。好消息是,现在有一款完全免费的AI股票分析工具——dai…

c++ this 指针的用途

c++ this 指针的用途

2026/7/24 21:22:15

C++ this 指针 超通俗讲解 我用最简单、最容易记住的方式给你讲清楚 this 指针到底是什么、用来干嘛。 一、this 是什么? this 是 C++ 类里自带的一个隐藏指针它指向 当前调用这个成员函数的对象自己。 你可以理解成:this = 我自己(当前对象) 二、this 指针 4 个核心用途…

Windows右键菜单终极管理工具:ContextMenuManager让你的桌面操作快如闪电

Windows右键菜单终极管理工具:ContextMenuManager让你的桌面操作快如闪电

2026/7/24 21:22:15

Windows右键菜单终极管理工具:ContextMenuManager让你的桌面操作快如闪电 【免费下载链接】ContextMenuManager 🖱️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否曾经因为Windows右键…

PG 日报|修复高 IO 并发场景,解决预读机制耗尽本地缓冲区缺陷

PG 日报|修复高 IO 并发场景,解决预读机制耗尽本地缓冲区缺陷

2026/7/24 21:22:15

PostgreSQL 技术文章 使用 Neon 后端构建的 GitHub 克隆代理 一位工程师在 GitHub 宕机期间,让 AI agent 使用 Neon 仍处于测试阶段的新 backend 套件,搭建了一个可运行的 Git 托管服务。作者此前对 Git 服务端内部机制毫无了解,但实验结果出…

告别手动录制:40+平台直播自动化监控全攻略

告别手动录制:40+平台直播自动化监控全攻略

2026/7/24 21:22:15

告别手动录制:40平台直播自动化监控全攻略 【免费下载链接】DouyinLiveRecorder 可循环值守和多人录制的直播录制软件,支持抖音、TikTok、Youtube、快手、虎牙、斗鱼、B站、小红书、pandatv、sooplive、flextv、popkontv、twitcasting、winktv、百度、微…

AI智能体与具身智能关系误区纠偏(10)

AI智能体与具身智能关系误区纠偏(10)

2026/7/24 21:22:15

前沿技术探索:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,是集深度强化学习(DRL)、卷积神经网络(CNN…

本地千万级图库秒级检索:ImageSearch让你的图片管理不再迷茫

本地千万级图库秒级检索:ImageSearch让你的图片管理不再迷茫

2026/7/24 21:12:15

本地千万级图库秒级检索:ImageSearch让你的图片管理不再迷茫 【免费下载链接】ImageSearch 基于.NET10的本地硬盘千万级图库以图搜图案例Demo和图片exif信息移除小工具分享 项目地址: https://gitcode.com/gh_mirrors/im/ImageSearch 你是否曾在数千张照片中…

微服务进阶:服务网格与Istio

微服务进阶:服务网格与Istio

2026/7/24 4:17:29

541|微服务进阶:服务网格与Istio 上篇文章我们聊了微服务的基本概念和拆分方法。 但微服务多了,问题也多了: 服务之间怎么通信? 怎么监控每个服务的调用链路? 熔断、限流、重试怎么做? 安全认证怎么统一? 以前这些都靠SDK库(比如Hystrix、Feign),每个服务都要集成…

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

2026/7/24 19:29:25

一、零售门店全域协同业务背景与行业痛点 1.1 门店超级终端设备矩阵(连锁便利店/商超标准配置) 自助收银Kiosk一体机:顾客结算、自助核销优惠券、商品素材预览;运营折叠平板:店长后台商品上新、图片录入、活动配置、…

噗叽短视频界面分析

噗叽短视频界面分析

2026/7/23 1:54:13

1 和小红书类似,可以采用类似判断方法------------其实他比小红书好判断,因为他没有图片,控件位置几乎是固定的,都不用判断------------2 因为他没有点赞按钮------------而且几乎所有控件位置都是完全一样的,所以我就…

Django毕设项目:基于 Django 的 智能化学生综合素质测评审核系统 校园学生评优评奖综合管理系统(源码+文档,讲解、调试运行,定制等)

Django毕设项目:基于 Django 的 智能化学生综合素质测评审核系统 校园学生评优评奖综合管理系统(源码+文档,讲解、调试运行,定制等)

2026/7/24 0:01:07

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

[具身智能-634]:Python 封装的地平线 VIO 多媒体库:libsrcampy库详解

[具身智能-634]:Python 封装的地平线 VIO 多媒体库:libsrcampy库详解

2026/7/24 0:01:07

srcampy /libsrcampy 名称释义先明确结论: 官方文档没有公布标准化英文全称,是地平线内部项目缩写;行业公认拆解如下:srcampy Source Amplifier Python bindingsrc Source(图像源:MIPI Sensor、视频源&am…

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

2026/7/24 0:01:07

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…