模式匹配
近几年工作中大量使用erlang开发,除了天然支持分布式外,erlang的模式匹配最值得称道。其他语言golang,scala也提供模式匹配,总觉得表达不够丰富,用起来也别扭,当然有可能是与自己对这两门语言本身理解不深有关。直到遇到rust,才找回那种自由的感觉。模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。结合使用模式和 match
表达式以及其他结构可以提供更多对程序控制流的支配权。模式由如下一些内容组合而成:
- 字面值
- 解构的数组、枚举、结构体或者元组
- 变量
- 通配符
- 占位符
一个与 if let
结构类似的是 while let
条件循环,它允许只要模式匹配就一直进行 while
循环。
现在我们见过了很多使用模式的方式了,不过模式在每个使用它的地方并不以相同的方式工作;在一些地方,模式必须是 irrefutable 的,意味着他们必须匹配所提供的任何值。在另一些情况,他们则可以是 refutable 的。
let
语句、 函数参数和 for
循环只能接受不可反驳的模式,因为通过不匹配的值程序无法进行有意义的工作。if let
和 while let
表达式被限制为只能接受可反驳的模式,因为根据定义他们意在处理可能的失败:条件表达式的功能就是根据成功或失败执行不同的操作。
在 match
表达式中,可以使用 |
语法匹配多个模式,它代表 或(or)的意思。
...
语法允许你匹配一个闭区间范围内的值。
也可以使用模式来解构结构体、枚举、元组和引用,以便使用这些值的不同部分。
有一些简单的方法可以忽略模式中全部或部分值:使用 _
模式(我们已经见过了),在另一个模式中使用 _
模式,使用一个以下划线开始的名称,或者使用 ..
忽略所剩部分的值。
对于有多个部分的值,可以使用 ..
语法来只使用部分并忽略其它值,同时避免不得不每一个忽略值列出下划线。
匹配守卫(match guard)是一个指定与 match
分支模式之后的额外 if
条件,它也必须被满足才能选择此分支。
at 运算符(@
)允许我们在创建一个存放值的变量的同时测试其值是否匹配模式。
rust的高级特征
四类可以在不安全 Rust 中进行而不能用于安全 Rust 的操作:
- 解引用裸指针
- 调用不安全的函数或方法
- 访问或修改可变静态变量
- 实现不安全 trait
与引用和智能指针的区别在于,记住裸指针
- 允许忽略借用规则,可以同时拥有不可变和可变的指针,或多个指向相同位置的可变指针
- 不保证指向有效的内存
- 允许为空
- 不能实现任何自动清理功能
常量与不可变静态变量可能看起来很类似,不过一个微妙的区别是静态变量中的值有一个固定的内存地址。使用这个值总是会访问相同的地址。另一方面,常量则允许在任何被用到的时候复制其数据。
生命周期高级特征:
- 生命周期子类型(lifetime subtyping),一个确保某个生命周期长于另一个生命周期的方式
- 生命周期 bound(lifetime bounds),用于指定泛型引用的生命周期
- trait 对象生命周期(trait object lifetimes),以及他们是如何推断的,以及何时需要指定
- 匿名生命周期:使(生命周期)省略更为明显
Rust 的 生命周期子类型(lifetime subtyping)功能,这是一个指定一个生命周期不会短于另一个的方法。在声明生命周期参数的尖括号中,可以照常声明一个生命周期 'a
,并通过语法 'b: 'a
声明一个不短于 'a
的生命周期 'b
。
可以使用匿名生命周期,'_,消除噪声
trait占位符
这里默认泛型类型位于 Add
trait 中。这里是其定义:
trait Add<RHS=Self> {
type Output;
fn add(self, rhs: RHS) -> Self::Output;
}
这看来应该很熟悉,这是一个带有一个方法和一个关联类型的 trait。比较陌生的部分是尖括号中的 RHS=Self
:这个语法叫做 默认类型参数(default type parameters)。RHS
是一个泛型类型参数(“right hand side” 的缩写),它用于定义 add
方法中的 rhs
参数。如果实现 Add
trait 时不指定 RHS
的具体类型,RHS
的类型将是默认的 Self
类型,也就是在其上实现 Add
的类型。
完全限定语法,这是调用函数时最为明确的方式。