The Rust Programming Language - 第18章 模式与模式匹配 - 18.1 所有可能会遇到模式的位置

18 模式与模式匹配

模式是Rust中的特殊语法,用来匹配类型中的结构,无论类型复杂与否。模式由以下一些内容组合而成:

字面值\解构的数组、枚举、元组或者结构体\变量\通配符\占位符,这些部分描述了我们需要处理的数据形状。(匹配模式其实可以理解为匹配项,简单理解就是把两个项目拉起来比较,看等不等于,等于的话我们就执行一些代码,不等于的话执行另一些代码。这个点就跟条件语句外加等于号一样,只不过Rust中把它专门做了个匹配模式)

18.1 所有可能会遇到模式的位置

Rust中有很多地方都会用到匹配模式

match 分支

我们在之前就见过match 表达式,我们这里再来复习一下,它的组陈元素match关键字、用于匹配的值VALUE和一个或者多个分支。当分支模式匹配到时,执行分支后的表达式

match VALUE {
    PATTERN => EXPRESSION,
    PATTERN => EXPRESSION,
    PATTERN => EXPRESSION,
}

match表达式必须穷尽,我们可以使用特定的模式_匹配所有情况,不过它从不绑定任何变量

if let 条件表达式

if let 我们之前也了解过,它只关心一种情况,当然它可以再带有一个可选的else,在if let 中的模式不匹配时运行

我们再来看一个例子:if let \ else if let\ else if 表达式的组合运用,这样比match表达式更灵活,它们分支条件也并不要求相互关联

fn main() {
    let favorite_color:Option<&str> = None;
    let is_tuseday = false;
    let age:Result<u8,_> = "34".parse();

    if let Some(color) =favorite_color  {
        println!("Using your favorite color, {}, as the background",color);
    }else if is_tuseday {
        println!("Tuesday is green day!")
    }else if let Ok(age)=age {
        if age >30 {
            println!("Using purple as the background color");
        }else {
            println!("Using orange as the background color");
        }
    } else {
        println!("Using the blue as the background color");
    }
}

如果用户指定了颜色,那么使用其作为背景颜色,如果今天是星期二,那么背景色为绿色,如果用户指定了年龄并且能够被解析为数字,根据数字大小指定是紫色还是橙色

我们可以使用类似于这样的表达式实现复杂的需求

注意:if let也可以像match分支那样引入覆盖变量,if let Ok = age引入了一个新的覆盖变量age,它包含Ok成员中的值,这意味着if age >30 需要位于这个代码块中,不能将两个条件组合为if let Ok(age) = age && age > 30,因为我们希望与30进行比较的被覆盖的age直到大括号开始的新作用域才是有效的

if let 表达式的缺点在于其穷尽性没有被编译器所检查,而match则被检查了。这意味着去过去掉最后的else块而遗漏一些处理情况编译器也不会警告这类可能的逻辑错误

while let 条件循环

一个与if let结构类似的是while let 条件循环,它允许只要模式匹配就一直进行while循环

fn main() {

let mut stack = Vec::new();

stack.push(1);
stack.push(2);
stack.push(3);

while let Some(top) = stack.pop() {
    println!("{}",top);
}
}

使用while let循环只要stack.pop()返回Some就打印出其值

pop方法会取出vector的最后一个元素并返回Some(value),如果vector是空的,它返回None。运行结果

3
2
1

for 循环

for循环是Rust中最常见的一个结构,不过for也可以获取一个模式。在for循环中,模式是for关键字直接跟随的值,正如for x in y 中的x

fn main() {

let v = vec!['a','b','c'];

for (index,value) in v.iter().enumerate() {
    println!("{} is at index {}",value,index)
}
}

这里使用enumerate方法适配一个迭代器来产生一个值和其在迭代器中的索引,它们位于一个元组中

第一个enumerate调用会产生元组(0,‘a’),当这个值匹配模式(index,value),index将会是0而value将会是‘a’,并打印出第一行输出

a is at index 0
b is at index 1
c is at index 2

let 语句

let语句其实就是在使用模式

let x = 5;
let (x,y,z) = (1,2,3)

这个解构将元组与模式匹配。Rust会比较值(1,2,3)与模式(x,y,z)并发现此值匹配这个模式,如果错误匹配的话,可以发现如下值:

let (x,y) = (1,2,3);

mismatched types
 --> src/main.rs:9:5
  |
9 | let (x,y) = (1,2,3);
  |     ^^^^^   ------- this expression has type `({integer}, {integer}, {integer})`
  |     |
  |     expected a tuple with 3 elements, found one with 2 elements
  |
  = note: expected tuple `({integer}, {integer}, {integer})`
             found tuple `(_, _)`

函数参数

函数参数可以是模式,我们来写一个函数

fn foo(x:i32) {
    //代码
}

x部分就是一个模式!类似于之前对let所做的,可以在函数参数紫红匹配元组

fn print_coordinates(&(x,y):&(i32,i32)) {
    println!("Current location: ({},{})",x,y);
}

fn main() {
    let point = (3, 5);
1
    print_coordinates(&point);
}

在一个参数中解构元组的函数

这会打印出Current location:(3,5)。值&(3,5)会匹配模式&(x,y),如此x得到了值3,而y得到了值5

闭包类似于函数,也可以在闭包参数列表中使用模式

我们现在已经了解在很多地方都使用模式了,但是模式在每个地方并不以相同的方式工作,接下来我们来讨论这两个值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值