特殊类型和特征
Rust 编译器知道标准库中存在的某些类型和特征。本章记录这些类型和特征的特殊功能。
Box<T>
Box<T>
具有 Rust 当前不允许用户定义的类型使用的一些特殊功能。
Box<T>
的 解引用运算符 产生一个可以从中移动的位置。这意味着*
运算符和Box<T>
的析构函数是语言内置的。- 方法 可以将
Box<Self>
作为接收者。 - 可以在
T
所在的 crate 中为Box<T>
实现 trait,而 孤儿规则 会阻止为其他泛型类型实现。
Rc<T>
Arc<T>
Pin<P>
UnsafeCell<T>
std::cell::UnsafeCell<T>
用于 内部可变性。它确保编译器不会执行对这种类型不正确的优化。它还确保具有内部可变性的类型的 static
项 不会被放置在标记为只读的内存中。
PhantomData<T>
std::marker::PhantomData<T>
是一个零大小、最小对齐的类型,为了 方差、drop check 和 自动 trait 的目的,它被认为拥有一个 T
。
运算符 Trait
std::ops
和 std::cmp
中的 trait 用于重载 运算符、索引表达式 和 调用表达式。
Deref
和 DerefMut
除了重载一元 *
运算符之外,Deref
和 DerefMut
还用于 方法解析 和 解引用强制转换。
Drop
Drop
trait 提供一个 析构函数,在要销毁此类型的值时运行。
Copy
Copy
trait 更改了实现它的类型的语义。类型实现 Copy
的值在赋值时会被复制而不是移动。
Copy
只能为不实现 Drop
且其字段均为 Copy
的类型实现。对于枚举,这意味着所有变体的所有字段都必须为 Copy
。对于联合体,这意味着所有变体都必须为 Copy
。
Copy
由编译器为以下类型实现
Clone
Clone
trait 是 Copy
的超 trait,因此它也需要编译器生成的实现。编译器为以下类型实现它
Send
Send
trait 表示此类型的值可以安全地从一个线程发送到另一个线程。
Sync
Sync
trait 表示此类型的值可以安全地在多个线程之间共享。必须为在不可变 static
项 中使用的所有类型实现此 trait。
Termination
Termination
trait 表示 main 函数 和 测试函数 的可接受的返回类型。
自动 trait
Send
、Sync
、Unpin
、UnwindSafe
和 RefUnwindSafe
这些 trait 是自动 trait。自动 trait 具有特殊属性。
如果未为给定类型的自动 trait 写出显式实现或负实现,则编译器会根据以下规则自动实现它
- 如果
T
实现 trait,则&T
、&mut T
、*const T
、*mut T
、[T; n]
和[T]
实现该 trait。 - 函数项类型和函数指针会自动实现该 trait。
- 如果结构体、枚举、联合体和元组的所有字段都实现该 trait,则它们会实现该 trait。
- 如果闭包的所有捕获类型都实现该 trait,则闭包会实现该 trait。通过共享引用捕获
T
和通过值捕获U
的闭包,会实现&T
和U
都实现的任何自动 trait。
对于泛型类型(将上述内置类型视为 T
的泛型),如果存在泛型实现,则编译器不会自动为可以使用该实现但又不满足所需 trait 约束的类型实现它。例如,标准库为所有 &T
(其中 T
为 Sync
)实现 Send
;这意味着如果 T
为 Send
但不是 Sync
,则编译器不会为 &T
实现 Send
。
自动 trait 也可以具有负实现,如标准库文档中所示的 impl !AutoTrait for T
,这会覆盖自动实现。例如,*mut T
具有 Send
的负实现,因此即使 T
为 Send
,*mut T
也不是 Send
。目前没有稳定的方法来指定额外的负实现;它们仅存在于标准库中。
自动 trait 可以作为额外的边界添加到任何 trait 对象 中,即使通常只允许一个 trait。例如,Box<dyn Debug + Send + UnwindSafe>
是一个有效的类型。
Sized
Sized
trait 表示此类型的大小在编译时已知;也就是说,它不是 动态大小类型。类型参数(除了 trait 中的 Self
)默认是 Sized
的,关联类型 也是如此。Sized
始终由编译器自动实现,而不是由 实现项 实现。这些隐式的 Sized
边界可以通过使用特殊的 ?Sized
边界来放松。