特殊类型和特征

Rust 编译器识别标准库中存在的某些类型和特征。本章记录了这些类型和特征的特殊功能。

Box<T>

Box<T> 有一些 Rust 目前不允许用户定义类型的特殊功能。

  • Box<T>解引用运算符会生成一个可以移动的位置。这意味着 * 运算符和 Box<T> 的析构函数是内置于语言中的。
  • 方法可以将 Box<Self> 作为接收者。
  • 可以在与 T 相同的包中为 Box<T> 实现特征,而孤儿规则阻止了其他泛型类型的这种行为。

Rc<T>

方法可以将 Rc<Self> 作为接收者。

Arc<T>

方法可以将 Arc<Self> 作为接收者。

Pin<P>

方法可以将 Pin<P> 作为接收者。

UnsafeCell<T>

std::cell::UnsafeCell<T> 用于内部可变性。它确保编译器不会执行对此类类型不正确的优化。它还确保具有内部可变性类型的static不会放置在标记为只读的内存中。

PhantomData<T>

std::marker::PhantomData<T> 是一种零大小、最小对齐的类型,出于方差丢弃检查自动特征的目的,它被认为拥有一个 T

运算符特征

std::opsstd::cmp 中的特征用于重载运算符索引表达式调用表达式

DerefDerefMut

除了重载一元 * 运算符外,DerefDerefMut 还用于方法解析解引用强制转换

Drop

Drop 特征提供了一个析构函数,每当要销毁此类型的某个值时就会运行该函数。

Copy

Copy 特征会更改实现它的类型的语义。类型实现 Copy 的值在赋值时会被复制而不是移动。

Copy 只能为不实现 Drop 且其字段均为 Copy 的类型实现。对于枚举,这意味着所有变体的 所有字段都必须是 Copy。对于联合体,这意味着所有变体都必须是 Copy

编译器为以下类型实现了 Copy

Clone

Clone 特征是 Copy 的超特征,因此它也需要编译器生成的实现。编译器为以下类型实现了它

  • 具有内置 Copy 实现的类型(见上文)
  • Clone 类型的元组
  • 仅捕获 Clone 类型的值或不从环境中捕获任何值的闭包

Send

Send 特征表示将此类型的值从一个线程发送到另一个线程是安全的。

Sync

Sync 特征表示在多个线程之间共享此类型的值是安全的。必须为不可变static中使用的所有类型实现此特征。

终止

Termination 特征指示主函数测试函数的可接受返回类型。

自动特征

SendSyncUnpinUnwindSafeRefUnwindSafe 特征是_自动特征_。自动特征具有特殊属性。

如果未为给定类型的自动特征写出显式实现或否定实现,则编译器会根据以下规则自动实现它

  • 如果 T 实现了该特征,则 &T&mut T*const T*mut T[T; n][T] 也实现该特征。
  • 函数项类型和函数指针自动实现该特征。
  • 如果结构体、枚举、联合体和元组的所有字段都实现了该特征,则它们也实现该特征。
  • 如果闭包的所有捕获的类型都实现了该特征,则该闭包也实现该特征。通过共享引用捕获 T 并通过值捕获 U 的闭包实现 &TU 都实现的任何自动特征。

对于泛型类型(将上述内置类型计为 T 上的泛型),如果泛型实现可用,则编译器不会为可以使用该实现但未满足必要特征边界的类型自动实现它。例如,标准库为所有 &T 实现 Send,其中 TSync;这意味着如果 TSend 但不是 Sync,则编译器不会为 &T 实现 Send

自动 trait 也可以有负面实现,在标准库文档中显示为 impl !AutoTrait for T,它会覆盖自动实现。例如,*mut TSend 有一个负面实现,因此 *mut T 不是 Send,即使 T 是。目前还没有稳定的方法来指定额外的负面实现;它们只存在于标准库中。

自动 trait 可以作为附加边界添加到任何 trait 对象,即使通常只允许一个 trait。例如,Box<dyn Debug + Send + UnwindSafe> 是一个有效的类型。

Sized

Sized trait 表示此类型的大小在编译时已知;也就是说,它不是 动态大小类型类型参数(trait 中的 Self 除外)默认情况下是 Sized关联类型 也是如此。Sized 始终由编译器自动实现,而不是由 实现项 实现。这些隐式 Sized 边界可以通过使用特殊的 ?Sized 边界来放宽。