大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。第二十四天还是继续和大家一起学习 Rust😊
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情
Copy trait
pub trait Copy: Clone {}
Copy trait 只是一个标记 trait(marker trait),所以要实现 Copy trait 的话,必须要实现 Clone trait,然后实现一个空的 Copy trait。这样的 trait 虽然没有任何的行为,但是它可以用作 trait bound 来进行类型安全检查,所以称为标记 trait
如果有数据结构的所有字段都实现了 Copy,那么就可以用 #[derive(Copy)] 宏来为数据结构实现 Copy,如果类型实现了 Copy ,那么在赋、函数调用时,值会被拷贝,否则所有权会被移动
不可变引用实现了 Copy,而可变引用 &mut T 没有实现 Copy。因为如果可变引用实现了 Copy trait,那么生成的一个可变引用然后把它赋值给另一个变量时,就会违背同一个作用域下只能有一个可变引用的所有权规则
Drop trait
pub trait Drop {
fn drop(&mut self);
}
大部分场景下不需要为数据结构提供 Drop trait,默认会依次对数据结构每个域做 drop,但有两种特殊情况下,需要手工实现 Drop:
- 希望在数据结束生命周期的时候做一些逻辑,例如记下日志
- 需要对资源回收的场景,例如释放锁
Copy trait 和 Drop trait 是互斥的,两者不能共存。因为 Copy 是按位做浅拷贝,那么它会默认拷贝的数据没有需要释放的资源,而 Drop 是为了释放额外的资源
标记 trait:Sized / Send / Sync / Unpin
Sized
sized trait 是用于标记有具体大小的类型,在使用泛型参数时,Rust 编译器会自动为泛型参数加上 Sized 约束
struct Data<T> {
inner: T,
}
// 相当于这个
struct Data<T: Sized> {
inner: T,
}
如果需要 T 是可变类型,那么就需要使用 ?Sized 来摆脱这个约束。如果开发者显式定义了 T: ?Sized ,那么 T 就是任意大小
Send / Sync
pub unsafe auto trait Send {}
pub unsafe auto trait Sync {}
这两个 trait 都是 unsafe auto trait,auto 代表编译器在合适的场合会自动为数据结构添加它们的实现。Send 和 Sync 是 Rust 并发安全的基础
- 如果一个类型 T 实现了 Send trait,那么意味着 T 可以安全的从一个线程移动到另一个线程,也就是说所有权可以在线程间移动
- 如果一个类型 T 实现了 Sync trait,那么意味着 &T 可以安全在多个线程中共享,一个类型 T 满足 Sync trait,那么相当于 &T 满足 Send trait
此文章为2月Day3学习笔记,内容来源于极客时间《Rust 编程第一课》