Rust学习笔记(五十三)模式(匹配)及其用法和可辩驳性
模式
模式是Rust中一种特殊的语法,用于匹配复杂和简单类型的结构。将模式与匹配表达式和其它构造结合使用,可以更好地控制程序的控制流。 模式由以下元素(的一些组合)组成: 字面值 解构的数组、枚举、结构体和元组 变量 通配符 占位符
想要使用模式,需要将其与某个值进行比较,如果模式匹配,就可以在代码中使用这个值的相应部分。 match的分支match VALUE { PATTERN => EXPRESSION, PATTERN => EXPRESSION, PATTERN => EXPRESSION, }
match表达式的要求:详尽(包含所有可能性) 一个特殊的模式_(下划线): 它会匹配任意东西 不会绑定到变量 通常用于match的最后一个分支,或用于忽略某些值 条件if let表达式
if let表达式主要是作为一种简短的方式来等价的代替只有一个匹配项的match。if let可选的可以拥有else,包括: else if else if let
但是if let不会检查穷尽性。例: fn main() { let favorite_color: Option<&str> = None; let is_tuesday = false; let age: Result = "34".parse(); if let Some(color) = favorite_color { println!("Using your favorite color, {}, as the background", color); } else if is_tuesday { 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 blue as the background color"); } }
运行以上代码,因为favorite_color是None,所以与if let不匹配;is_tuesday是false,也不能进入else if;age是Ok(T),所以能够匹配,并且把age的值34给Ok中的变量age,最后34 > 30,所以输出Using purple as the background color。 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); } }
运行以上代码,只要stack中还能pop出值,循环可以一直进行。 for循环
for循环是Rust中最常见的循环。在for循环中,模式就是紧随着for关键字后的值,例: fn main() { let v = vec!["a", "b", "c"]; for (index, value) in v.iter().enumerate() { println!("{} is at index {}", value, index); } } let语句
let语句也是模式,let PATTERN = EXPRESSION,例: fn main() { let x = 8;//x 是一个代表 "将匹配到的值绑定到变量 x" 的模式。 //同时因为名称 x 是整个模式,这个模式实际上等于 //"将任何值绑定到变量 x,不管值是什么"。 let (x, y, z) = (1, 2, 3);//模式解构元组 //let (x, y) = (1, 2, 3);不匹配,编译报错 } 函数参数
函数参数也可以是模式,例: fn print_coordinates(&(x, y): &(i32, i32)) { println!("Current location: ({}, {})", x, y); } fn main() { let point = (3, 5); print_coordinates(&point); } 可辩驳性:模式是否会无法匹配
模式的两种形式: 可辨驳的(对于某些可能的值,无法进行匹配的模式)例如if let Some(x) = a_value,当右边是None是就无法匹配 不可辩驳的(能匹配任何可能传递的值的模式,不可能失败的,怎么都会成功)例如let x = 5;
函数参数、let语句、for循环只接受不可辩驳的模式。而if let和while let接受可辨驳和不可辩驳的模式。例: fn main() { let x = Some(5); let Some(a) = x;//let只接受不可辩驳,但x是Option类型,可能是Some,也有可能是None导致不匹配。所以报错 if let Some(a) = x {//改为if let就没有错误 } }