类型
types.md
commit: af1cf6d3ca3b7a8c434c142148742aa912e37c34
本章译文最后维护日期:2020-11-14
Rust 程序中的每个变量、程序项和值都有一个类型。值的类型定义了该如何解释用于保存它的内存数据,以及定义了可以对该值执行的操作。
内置的类型以非平凡的方式(in nontrivial ways)紧密地集成到语言中,这种方式是不可能在用户定义的类型中模拟的。用户定义的类型功能有限。
内置类型列表:
- 原生类型(primitive types):
- 布尔型(Boolean) —
true
或false
- 数字类(Numeric) — 整型(integer) 和 浮点型(float)
- 文本类(Textual) — 字符型(
char
) 和 字符串切片(str
) - never类型 —
!
— 没有值的类型
- 布尔型(Boolean) —
- 序列类型(sequence types):
- 用户自定义类型(user-defined types):
- 函数类型(function types):
- 指针类型(pointer types):
- trait类型(Trait types):
类型表达式
句法
Type :
TypeNoBounds
| ImplTraitType
| TraitObjectTypeTypeNoBounds :
ParenthesizedType
| ImplTraitTypeOneBound
| TraitObjectTypeOneBound
| TypePath
| TupleType
| NeverType
| RawPointerType
| ReferenceType
| ArrayType
| SliceType
| InferredType
| QualifiedPathInType
| BareFunctionType
| MacroInvocation
上表中的 Type 文法规则中定义的各种类型表达式都是某个具体类型的句法产生式。它们可以覆盖指代:
- 序列类型(tuple, array, slice)。
- 类型路径(type paths),这些包括:
- 指针类型(引用, 裸指针, 函数指针)。
- 自动推断型类型(inferred type),就是请求编译器确定类型的类型。
- 用来消除歧义的圆括号。
- Trait类型:trait对象(trait object) 和 实现trait(impl trait).
- never型(
!
)。 - 展开成类型表达式的宏。
圆括号组合类型
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)))); }