常州网站推广多少钱,全国知名网站建设公司,设计一套网站价格,全网推广代运营喜欢的话别忘了点赞、收藏加关注哦#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵#xff01;(#xff65;ω#xff65;)
6.3.1. 什么是match
match允许一个值与一系列模式进行匹配#xff0c;并执行匹配的模式对应的代码。模式可以是字面值、变量名、通配符等…喜欢的话别忘了点赞、收藏加关注哦对接下来的教程有兴趣的可以关注专栏。谢谢喵(ω)
6.3.1. 什么是match
match允许一个值与一系列模式进行匹配并执行匹配的模式对应的代码。模式可以是字面值、变量名、通配符等等。
将match表达式想象为硬币分类机硬币沿着带有不同大小孔的轨道滑下每枚硬币都会从它遇到的第一个适合的孔落下。以同样的方式值会遍历match中的每个模式并且在第一个模式中值“适合”该值落入要在执行期间使用的关联代码块中。
6.3.2. match的应用
来看个例子编写一个函数接受一枚未知的美国硬币并以与计数机类似的方式确定它是哪种硬币并返回其价值以美分为单位。
enum Coin {Penny,// 1美分Nickel,// 5美分Dime,// 10美分Quarter,// 25美分
}fn value_in_cents(coin: Coin) - u8 {match coin {Coin::Penny 1,Coin::Nickel 5,Coin::Dime 10,Coin::Quarter 25,}
}match关键字后跟一个表达式在本例中是值 coin 。这看起来与if中使用的条件表达式非常相似但有一个很大的区别if 的条件需要布尔值但match可以是任何类型。本例中的coin类型是我们在第一行定义的Coin枚举。 然后是花括号花括号里有4个分支(英文叫arm)每个分支都是由待匹配的模式和它对应的代码来组成的。第一个分支Coin::Penny 1,就使用Coin::Penny作为它的模式中间的分隔模式和要运行的代码这里要运行代码就是值1也就是返回1这个值。不同的分支之间使用,隔开。 match表达式执行时会把match后的表达式在这里是coin从上到下依次与里面的分支进行比较如果模式与值匹配则执行与该模式关联的代码。如果该模式与值不匹配则继续执行下一个分支。匹配成功的分支所对应的代码表达式会作为整个match表达式的值进行返回。 比如说match匹配到5美分也就是Coin::Nickel上了那么整个表达式的值就是5。又因为match表达式是value_in_cents这个函数中的最后一个表达式所以它的值也就是5会作为函数的返回值。 这里因为每个分支对应的代码都很简单所以用就可以了但如果一个分支对应的是多行代码就需要用花括号把多行代码括起来。如下例
fn value_in_cents(coin: Coin) - u8 {match coin {Coin::Penny {println!(Lucky penny!);1}Coin::Nickel 5,Coin::Dime 10,Coin::Quarter 25,}
}6.3.3. 绑定值的模式
匹配的分支可以绑定到被匹配对象的部分值通过这个功能就可以从枚举类型的变体中提取值。
看个例子一位朋友正在尝试收集全部 50 个州 25 美分。当我们按硬币类型对零钱进行分类时我们还会标出与每个25美分相关的州名称美国州太多了这里就只写了Alabama和Alaska这两个州
#[derive(Debug)] // 便于打印调试
enum UsState { Alabama, Alaska,
} enum Coin { Penny, Nickel, Dime, Quarter(UsState),
} fn value_in_cents(coin: Coin) - u8 { match coin { Coin::Penny { println!(Lucky penny!); 1 }, Coin::Nickel 5, Coin::Dime 10, Coin::Quarter(state) { println!(State quarter from {:?}!, state); 25 } }
} fn main() { let c Coin::Quarter(UsState::Alaska); println!({}, value_in_cents(c));
}让25美分硬币以下都叫Quarter所对应的Coin里的变体也就是Coin::Quarter给关联一个数据它关联的数据就是上面的这个枚举类型UsState。 在value_in_cents函数里也需要对Quarter所在的分支稍微修改一下匹配模式从Coin::Quarter修改到Coin::Quarter(state),意思就是把Coin::Quarter所关联的值绑定到state这个变量上在后面的代码块里面就可以使用state这个变量把Coin::Quarter所关联的值取出来进行使用。 在某些情境下Coin::Quarter所关联的值可能用不上这时候就可以用通配符_代表不关心里面的内容:Coin::Quarter(_) 在main函数里先声明了一个c变量存的是Coin::Quarter(UsState::Alaska)。也就是存储了Coin::Quarter这个变体然后其关联的值的是UsState::Alaska这个变体。最后又调用了一下value_in_cents函数。
看看输出效果
State quarter from Alaska!
256.3.4. 匹配OptionT
就以上一篇文章最后的代码例来做分析
fn main() { let x: i8 5; let y: Optioni8 Some(5); let sum match y { Some(value) x value, // 如果 y 是 Some则解包并相加 None x, // 如果 y 是 None则返回 x };
}如果y不为None就解包把Some所关联的值绑定到value上返回x value的值如果y为None就只返回x的值
6.3.5. match匹配必须穷举所有可能
Rust要求match覆盖到所有的可能性这样才能保证代码的安全有效。
以上一个代码为基础稍作修改
fn main() { let x: i8 5; let y: Optioni8 Some(5); let sum match y { Some(value) x value, };
}输出
error[E0004]: non-exhaustive patterns: None not covered-- src/main.rs:5:21|
5 | let sum match y {| ^ pattern None not covered|
note: Optioni8 defined here-- /Users/stanyin/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:571:1|
571 | pub enum OptionT {| ^^^^^^^^^^^^^^^^^^
...
575 | None,| ---- not covered note: the matched value is of type Optioni8
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown|
6 ~ Some(value) x value,
7 ~ None todo!(),|Rust捕捉到了None这个可能性没有被覆盖的错误所以报错。把处理None的分支加上就没问题了。
如果可能性太多或者不想处理其中一些可能性这个时候就可以使用通配符_。
6.3.6. 通配符
首先要把想处理的分支照常写上其他的使用通配符_代替即可。
看例子v是一个u8类型的变量判断v是否是0
use rand::Rng; // 使用外部库
fn main(){ let v: u8 rand::thread_rng().gen_range(0..255); // 生成随机数println!({}, v); match v { 0 println!(zero), _ println!(not zero), }
}u8有256个数256种可能使用match自然是不可能每个数都写一个分支所以就可以为0写一个分支其他的使用通配符_来代替。
输出
136
not zero