类型
Rust 程序中的每个变量、项和值都有一个类型。值的类型定义了其内存的解释方式以及可对该值执行的操作。
内置类型与语言紧密集成,以非常规的方式实现,用户定义类型无法模拟。
用户定义类型的功能有限。
类型的分类如下:
- 原始类型:
- 序列类型:
- 用户定义类型:
- 函数类型:
- 指针类型:
- Trait 类型:
类型表达式
Syntax
Type →
TypeNoBounds
| ImplTraitType
| TraitObjectType
TypeNoBounds →
ParenthesizedType
| ImplTraitTypeOneBound
| TraitObjectTypeOneBound
| TypePath
| TupleType
| NeverType
| RawPointerType
| ReferenceType
| ArrayType
| SliceType
| InferredType
| QualifiedPathInType
| BareFunctionType
| MacroInvocation
类型表达式是上述 Type 语法规则所定义的引用类型的语法。它可以引用:
- 推断类型,请求编译器来确定类型。
- 括号,用于消除歧义。
- Trait 类型:Trait 对象 和 impl trait。
- never 类型。
- 宏,展开为一个类型表达式。
括号类型
Syntax
ParenthesizedType → ( Type )
在某些情况下,类型的组合可能存在歧义。在类型周围使用括号可以消除歧义。例如,引用类型 中的 + 运算符对类型边界的作用域可能不明确,因此必须使用括号。需要此消歧方式的语法规则使用 TypeNoBounds 规则而非 Type。
#![allow(unused)]
fn main() {
use std::any::Any;
type T<'a> = &'a (dyn Any + Send);
}
递归类型
名义类型——结构体、枚举和联合体——可以是递归的。也就是说,每个 enum 变体或 struct 或 union 字段可以直接或间接地引用外围的 enum 或 struct 类型自身。
此类递归有若干限制:
- 递归类型必须包含一个名义类型在递归中(不仅仅是类型别名或其他结构类型如数组或元组)。因此
type Rec = &'static [Rec]是不允许的。 - 递归类型的大小必须是有限的;换句话说,类型的递归字段必须是指针类型。
递归类型的一个示例及其用法:
#![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))));
}