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

开头:菜鸟小明的疑惑

小明:

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

小李(笑):

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

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


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


Send 是啥?

小明:

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

小李:

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

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

rust 复制代码
let v = vec![1, 2, 3];

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

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

});

小李继续:

"像 Vec、String 这些常见类型,默认都实现了 Send。"


Sync 又是啥?

小明:

"那 Sync 呢?"

小李:

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

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

小李举例:

"但如果是 Rc,就不是 Sync,因为它没加锁,线程共享会炸!"

rust 复制代码
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 接口,不管是圆、方块、三角形,统统放一起画!"

rust 复制代码
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。


第三章:动态分发 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,练习对象安全规则!


结尾

小明:

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

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

"学 Rust,心累但放心!

相关推荐
凌峰的博客36 分钟前
基于深度学习的图像安全与隐私保护研究方向调研(中)
人工智能·深度学习·安全
步菲1 小时前
springboot canche 无法避免Null key错误, Null key returned for cache operation
java·开发语言·spring boot
知远同学7 小时前
Anaconda的安装使用(为python管理虚拟环境)
开发语言·python
小徐Chao努力7 小时前
【Langchain4j-Java AI开发】09-Agent智能体工作流
java·开发语言·人工智能
CoderCodingNo7 小时前
【GESP】C++五级真题(贪心和剪枝思想) luogu-B3930 [GESP202312 五级] 烹饪问题
开发语言·c++·剪枝
kylezhao20197 小时前
第1章:第一节 开发环境搭建(工控场景最优配置)
开发语言·c#
啃火龙果的兔子7 小时前
JavaScript 中的 Symbol 特性详解
开发语言·javascript·ecmascript
热爱专研AI的学妹8 小时前
数眼搜索API与博查技术特性深度对比:实时性与数据完整性的核心差异
大数据·开发语言·数据库·人工智能·python
网安INF8 小时前
网络杀伤链(CKC模型)与ATT&CK模型详解
网络·安全·网络安全·网络攻击模型
Mr_Chenph8 小时前
Miniconda3在Windows11上和本地Python共生
开发语言·python·miniconda3