rust Send Sync 以及对象安全和对象不安全

devtools/2025/3/22 21:27:15/

开头:菜鸟小明的疑惑

小明:

“李哥,我最近学 Rust,感觉它超级严谨,啥 Send、Sync、对象安全、静态分发、动态分发的,我都搞晕了!为啥 Rust 要设计得这么复杂啊?”

小李(笑):

“别急,Rust 是因为想让代码‘安全’,又‘高性能’,所以才有这么多机制。

我们从头讲,慢慢来,一定搞清楚。”

---

第一章:线程安全是怎么做到的?Send / Sync

---

Send 是啥?

小明:

“我知道线程是并发执行的,但 Rust 的 Send 是干嘛的?”

小李:

“Send 就是让类型可以在线程之间安全传递,所有权移动。

如果一个类型实现了 Send,说明你可以把它交给另一个线程,不会有问题。”

let v = vec![1, 2, 3];

std::thread::spawn(move || {

    println!("{:?}", v); // v 安全移动到线程里

});

小李继续:

“像 Vec<T>、String 这些常见类型,默认都实现了 Send。”

---

Sync 又是啥?

小明:

“那 Sync 呢?”

小李:

“Sync 是说,多个线程可以安全共享一个类型的 引用 &T。

比如 &i32 是 Sync,多个线程读 &i32 没问题。”

小李举例:

“但如果是 Rc<T>,就不是 Sync,因为它没加锁,线程共享会炸!”

use std::rc::Rc;

let rc = Rc::new(5);

std::thread::spawn(move || {

    println!("{}", rc); // 编译报错!Rc 不是 Send

});

---

Rust 怎么防止线程不安全?

小明:

“那怎么防止?我不小心就传了个 Rc 进去怎么办?”

小李(笑):

“防不住啊?放心!Rust 的编译器帮你守着!

你跨线程传东西,Rust 会自动检查类型有没有 Send 和 Sync,

不符合就不给你编译过!

连运行都跑不起来,根本不可能线程不安全。”

---

第二章:对象安全是干嘛的?

---

什么是对象安全?

小明:

“线程安全我懂了。那对象安全呢?”

小李:

“对象安全是另一回事,管的是多态和动态分发。”

“Rust 里,想通过 dyn Trait 传递 trait 对象,trait 必须是对象安全的。

否则 Rust 编译器不让用。”

---

对象安全有啥用?

小李:

“对象安全让我们可以搞‘接口多态’,

比如你想写一个 draw 接口,不管是圆、方块、三角形,统统放一起画!”

trait Drawable {

    fn draw(&self);

}

fn render(shape: &dyn Drawable) {

    shape.draw();

}

“你能写 &dyn Drawable,是因为 Drawable 满足对象安全。”

---

什么叫不对象安全?

小明:

“那为啥有些 trait 不对象安全?”

小李:

“比如有个方法返回 Self,

dyn Trait 根本不知道 Self 是谁,咋办?

编译器说:‘我拒绝!’”

trait Factory {

    fn create() -> Self; // 返回 Self,不对象安全

}

---

对象安全的规则

小李总结:

1. 方法不能返回 Self(除非在 Box、Arc 里包起来)。

2. 不能有泛型方法。

3. 接口方法的 self 必须是 &self、&mut self 或 Box<Self>。

---

第三章:动态分发 VS 静态分发

---

动态分发(对象安全)

小李:

“dyn Trait 背后有个 vtable 指针,

运行时根据类型调用不同的方法。

这种叫动态分发,更灵活,但有运行时开销。”

---

静态分发(泛型、高性能)

小李继续:

“泛型和不对象安全的 trait,

Rust 编译器会为每个类型单独生成代码,

这种叫静态分发,零开销、性能好。”

---

第四章:Rust 为什么这么设计?

---

小明:

“李哥,我觉得 Rust 好麻烦,为什么要搞这么复杂?”

小李(认真):

“为了安全和性能!

C/C++ 时代:线程不安全、指针乱飞、内存泄露。

Rust 时代:编译时发现所有问题,安全有保障。

还能零开销,静态分发快得飞。”

---

第五章:总结表格

---

第六章:练习时间!

小李:

“明白了?来,练习一下!”

写个 trait Shape,加 fn area(&self) -> f64;,实现 dyn Shape 多态!

写个 trait Cloneable,fn clone_box(&self) -> Box<dyn Cloneable>,练习对象安全规则!

---

结尾

小明:

“李哥,真香!终于懂了 Rust 的对象安全和线程安全!”

“原来 Rust 是怕你写出有 bug 的代码,所以宁愿麻烦点,也要你写安全、性能高的代码!”

“学 Rust,心累但放心!


http://www.ppmy.cn/devtools/169239.html

相关文章

Mac使用pycharm+基于Kaggle的社交媒体情绪分析数据集,用python做词云的可视化

pycharm版本 一开始用的专业版&#xff0c;但是太久没有写代码就账户过期了&#xff0c;找半天Activation Code也没有找到&#xff0c;重新下载一个社区版&#xff0c;我点进去是社区版的页面&#xff0c;但是下载结果是专业版&#xff0c;后面仔细看&#xff0c;mad社区版在下…

【HDLBits】Procedures合集

Always blocks 基础定义 由于数字电路是由用导线连接的逻辑门组成的&#xff0c;因此任何电路都可以表示为模块和赋值语句的某种组合。然而&#xff0c;有时这不是最方便的方式来描述电路。过程&#xff08;以always块为例&#xff09;为描述电路提供了另一种语法。 对于综合…

Cursor+MCP+Blender快速建模,Windows11环境

环境准备 Cursor (我的版本是0.47.8) Blender 3.0 或更高版本&#xff08;我的版本是3.3.1&#xff09; Python 3.10 或更高版本 安装UV https://docs.astral.sh/uv/getting-started/installation/ 1.安装blender-mcp插件 到https://github.com/ahujasid/blender-mcp下载插件…

零基础本地部署 ComfyUI+Flux.1 模型!5 分钟搭建远程 AI 绘图服务器(保姆级教程)

文章目录 前言1. 本地部署ComfyUI2. 下载 Flux.1 模型3. 下载CLIP模型4. 下载 VAE 模型5. 演示文生图6. 公网使用 Flux.1 大模型6.1 创建远程连接公网地址 7. 固定远程访问公网地址 前言 在如今这 AI 技术一路火花带闪电、疯狂往前冲的时代&#xff0c;图像生成模型那可不再是…

拥抱健康生活,开启养生之旅

在快节奏的现代生活中&#xff0c;健康养生愈发重要&#xff0c;它不仅能让我们保持良好状态&#xff0c;更是享受美好生活的基石。​ 饮食养生是健康的关键。我们应秉持均衡原则&#xff0c;一日三餐合理搭配。多摄入新鲜蔬果&#xff0c;它们富含维生素、矿物质与膳食纤维&a…

数组连续和 - 华为OD统一考试(C卷)

题目描述 给定一个含有N个正整数的数组&#xff0c;求出有多少连续区间&#xff08;包括单个正整数&#xff09;&#xff0c;它们的和大于等于 x。 输入描述 第一行为两个整数 N,x。(0<N≤100000, 0≤x≤10000000) 第二行有 N 个正整数 &#xff08;每个正整数小于等于 …

联想拯救者触摸板会每次开机都自动关闭、联想笔记本触摸板关闭、笔记本电脑触摸板自动关闭的解决方法

首先无硬性问题的话没有严重磕碰的话就不是外部受力问题 再看看驱动是否都正常更新了 再去看看是不是系统设置外接鼠标会自动关闭触摸板&#xff1f;触摸板也打开了功能也开了 最后只可能就是你的电脑某个关乎控制触摸板的软件导致的&#xff0c;没错就是联想自带的Legion Zone…

【Python】数据结构有Python版吗?

李升伟 整理 数据结构可以用Python实现。Python提供了多种内置数据结构&#xff0c;如列表&#xff08;list&#xff09;、元组&#xff08;tuple&#xff09;、集合&#xff08;set&#xff09;、字典&#xff08;dict&#xff09;等。此外&#xff0c;Python的标准库还包含一…