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,心累但放心!

相关推荐
Jackson@ML38 分钟前
如何快速高效学习Python?
开发语言·python
大小曲奇(´ε` )2 小时前
使用安全继电器的急停电路设计
安全
西瓜本瓜@2 小时前
在Android中如何使用Protobuf上传协议
android·java·开发语言·git·学习·android-studio
UFIT2 小时前
Python函数与模块笔记
开发语言·python
机智的人猿泰山2 小时前
java kafka
java·开发语言·kafka
go_to_hacker2 小时前
安恒web安全春招实战
安全·web安全·网络安全·渗透测试
Y1nhl3 小时前
搜广推校招面经八十一
开发语言·人工智能·pytorch·深度学习·机器学习·推荐算法·搜索算法
Algorithm15763 小时前
谈谈接口和抽象类有什么区别?
java·开发语言
YiSLWLL3 小时前
使用Tauri 2.3.1+Leptos 0.7.8开发桌面小程序汇总
python·rust·sqlite·matplotlib·visual studio code
yu4106213 小时前
Rust 语言使用场景分析
开发语言·后端·rust