《Rust 编程第一课》 学习笔记 day24

104 阅读3分钟

大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 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:

  1. 希望在数据结束生命周期的时候做一些逻辑,例如记下日志
  2. 需要对资源回收的场景,例如释放锁

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 编程第一课》