1. 结构体
1. 语法
一个结构体由几部分组成:
- 通过关键字
struct
定义 - 清晰明确的结构体名称
- 有名字和类型的结构体字段(field)
1 | struct User { |
通过为每个字段指定具体值来创建这个结构体的实例:
- 初始化实例时,每个字段都需要进行初始化
- 初始化时的字段顺序不需要和结构体定义时的顺序一致
- 当函数参数和结构体字段同名时,可以直接使用缩略的方式进行初始化
- 根据已有的结构体实例,创建新实例时,可以在尾部使用
..
简化赋值
1 | fn main() { |
通过 .
操作符,访问或修改结构体实例内部的字段值:
- 必须将结构体实例声明为可变的,才能修改其中的字段
- 不支持将结构体某个字段标记为可变
1 | user1.email = String::from("anotheremail@example.com"); |
2. 特殊结构体
1. 元组结构体(tuple struct)
定义与元组类似的结构体,结构体有名称,但是字段没有,其称为元组结构体。
1 | struct Color(i32, i32, i32); |
2. 单元结构体(Unit-like Struct)
可以一个没有任何字段的结构体,其被称为单元结构体。主要是为了在某个类型上实现 trait 但不需要在类型中存储数据的时候使用。
1 | struct AlwaysEqual; |
3. 结构体数据的所有权
如上 User 例子,我们希望某个结构体拥有它所有的数据,而不是从其它地方借用数据,于是使用了自身拥有所有权的 String
类型而不是基于引用的 &str
字符串切片类型。
当需要使结构体存储被其他对象拥有的数据的引用,需要使用生命周期(lifetime),来确保结构体的作用范围要比它所借用的数据的作用范围要小。
2. 枚举
枚举(enum 或 enumeration)允许通过列举可能的成员来定义一个枚举类型,每个元素成为成员(variants)。
1 | // IPv4 和 IPv6 的枚举 |
可以将数据信息关联到枚举成员上,特别的,与其他语言不同的是,同一个枚举类型下的不同成员还能持有不同的数据类型。
1 | // 扑克花色枚举 |
1. Option 枚举用于处理空值
Rust 中没有 null 关键字,它使用 Option 枚举,来处理空值。它被包含在了 prelude 中,不需要将其显式引入作用域就可以使用。
1 | enum Option<T> {// T 是泛型参数 |
3. 模式匹配
模式匹配最常用的就是 match
和 if let
。
1. match
match
类似其他语言中的 switch
,允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行对应的代码。
一般形式如下:
1 | match target { |
有几个注意事项:
- 匹配必须要穷举出所有可能,可以使用
_
或一个变量来代表未列出的其他可能性 - 每一个分支都必须是一个表达式,且所有分支的表达式最终返回值的类型必须相同
X|Y
,类似逻辑运算符或,代表该分支可以匹配 X 也可以匹配 Y,只要满足一个即可
1 | enum Direction { |
2. if let
用来处理只匹配一个模式的值而忽略其他模式的情况。
1 | if let Some(3) = v { |