类型

types.md
commit: af1cf6d3ca3b7a8c434c142148742aa912e37c34
本章译文最后维护日期:2020-11-14

Rust 程序中的每个变量、程序项和值都有一个类型。类型定义了该如何解释用于保存它的内存数据,以及定义了可以对该值执行的操作。

内置的类型以非平凡的方式(in nontrivial ways)紧密地集成到语言中,这种方式是不可能在用户定义的类型中模拟的。用户定义的类型功能有限。

内置类型列表:

类型表达式

句法
Type :
      TypeNoBounds
   | ImplTraitType
   | TraitObjectType

TypeNoBounds :
      ParenthesizedType
   | ImplTraitTypeOneBound
   | TraitObjectTypeOneBound
   | TypePath
   | TupleType
   | NeverType
   | RawPointerType
   | ReferenceType
   | ArrayType
   | SliceType
   | InferredType
   | QualifiedPathInType
   | BareFunctionType
   | MacroInvocation

上表中的 Type 文法规则中定义的各种类型表达式都是某个具体类型的句法产生式。它们可以覆盖指代:

圆括号组合类型

ParenthesizedType :
   ( Type )

在某些情况下,类型组合在一起时可能会产生二义性。此时可以在类型周围使用元括号来避免歧义。例如,引用类型类型约束列表中的 +运算符搞不清楚其左值的边界位置在哪里,因此需要使用圆括号来明确其边界。这里需要的消歧文法就是使用 TypeNoBounds 句法规则替代 Type 句法规则。

#![allow(unused)]
fn main() {
use std::any::Any;
type T<'a> = &'a (dyn Any + Send);
}

递归类型

标称类型(nominal types) — 结构体(struct)枚举(enum)联合体(union) — 可以是递归的。也就是说,每个枚举(enum)变体或结构体(struct)或联合体(union)的字段可以直接或间接地指向此枚举(enum)或结构体(struct)类型本身。这种递归有一些限制:

  • 递归类型必须在递归中包含一个标称类型(不能仅是类型别名或其他结构化的类型,如数组元组)。因此不允许使用 type Rec = &'static [Rec]
  • 递归类型的尺寸必须是有限的;也就是说,类型的递归字段必须是指针类型
  • 递归类型的定义可以跨越模块边界,但不能跨越模块可见性边界或 crate 边界(为了简化模块系统和类型检查)。

递归类型及使用示例:

#![allow(unused)]
fn main() {
enum List<T> {
    Nil,
    Cons(T, Box<List<T>>)
}

let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));
}