basic/match-pattern/pattern-match #664
Replies: 26 comments 23 replies
-
模式匹配有可驳模式和不可驳模式两种。 |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
新知识 get,原来处处都是模式匹配 |
Beta Was this translation helpful? Give feedback.
-
把模式(pattern)看作正则表达式就好理解多了 |
Beta Was this translation helpful? Give feedback.
-
感觉好奇怪啊这个东西。。。 |
Beta Was this translation helpful? Give feedback.
-
感觉非常像ts的解构赋值啊 |
Beta Was this translation helpful? Give feedback.
-
可辩驳性:模式是否会无法匹配§ 可辨驳的(对于某些可能的值,无法进行匹配的模式)例如if let Some(x) = a_value,当右边是None是就无法匹配 |
Beta Was this translation helpful? Give feedback.
-
匹配模式是rust的一种语法。 |
Beta Was this translation helpful? Give feedback.
-
感觉模式匹配的思想与 Coq 中“构造子”的思想很像 |
Beta Was this translation helpful? Give feedback.
-
没太明白 |
Beta Was this translation helpful? Give feedback.
-
let my_vec = [Some(1), Some(2), Some(3), Some(4), None, Some(6)];
let mut case5 = Vec::from(my_vec);
while let Some(tp) = case5.pop() {
println!("case success {:?}", tp);
} 为什么这段代码会产生: 这样的结果,难道不应该是在-2 索引时候退出 while 吗 Some(None) 是 while let 覆盖的结果? |
Beta Was this translation helpful? Give feedback.
-
人是不是越来越少了,评论少了不少 |
Beta Was this translation helpful? Give feedback.
-
这一大章还是没太懂 |
Beta Was this translation helpful? Give feedback.
-
之前在语句和表达式中有提到 let 未来可能会成为一种表达式,如果 let 真的成为了一种表达式,那么 if let 这种写法:
就会给人一种 |
Beta Was this translation helpful? Give feedback.
-
// Vec是动态数组 // 向数组尾部插入元素 // stack.pop从数组尾部弹出元素 while 这没理解,stack.pop()返回的是符合Some(top)的?还是说,所有的值都是option? |
Beta Was this translation helpful? Give feedback.
-
Rust果然有自己独立一套方法论,把赋值认为是一种模式匹配。对于 let x: i32 = 5, 变量名x是一种类似通配符的模式,只要数据类型相同就能配上。有留言说把模式理解成某种正则我认为是个有启发性的类比。但是目前我还看不出来Rust采用万物归于匹配的设计其优点何在?等待高人。 |
Beta Was this translation helpful? Give feedback.
-
在函数参数一节中 fn print_coordinates(&(x, y): &(i32, i32)) {
println!("Current location: ({}, {})", x, y);
}
fn main() {
let point = (3, 5);
print_coordinates(&point);
} 这其中我在自己的ide中试了一下发现 |
Beta Was this translation helpful? Give feedback.
-
在这里写下一些自己的理解。 重看 let 语句我将rust 中的赋值操作看作两个步骤,分别是模式匹配和变量绑定,将 let 语句中的变量看作通配符,可用来匹配并绑定该变量类型对应的所有值。 let x: i32 = 1i32; 如上面语句中的x变量,其类型为i32,所以x可以匹配i32类型下的所有值,可先将“ = ”左边看做一个集合,集合中的值为i32可表示的所有值(-231~231 - 1),而“ = ”右边为i32类型的一个值“1”。 步骤一:模式匹配 步骤二:变量绑定 几个模式匹配的例子enum Opt {
AAA,
BBB(u32),
CCC(i32, u32),
DDD { x: i32, y: u32 },
}
fn main() {
// "=" 左边是值的集合,右边是值的个例
let a: Opt = Opt::AAA; // 集合包括所有个例,可以匹配成功并进行变量绑定
let b: Opt = Opt::BBB(1); // 同上
let c: Opt = Opt::CCC(1, 2); // 同上
let d: Opt = Opt::DDD { x: 1, y: 2 }; // 同上
} 上面4条绑定语句中,因为变量类型都为Opt, 即各变量都可匹配Opt类型的所有值,所以” = “左边可看作类型为Opt的所有值的集合,而” = “右边的值都包含在集合中,所以都可以匹配成功,并将变量与值绑定。 // 集合只包括 Opt::BBB(u32)的所有值,而"="右边的个例类型为Opt, 即左边的集合中没有包括完右边个例的类型所应该包含的所有值,所有无法进行匹配
let Opt::BBB(x) = b; //error 上面的绑定语句中,” = “左边的值的集合为Opt::BBB(u32) ,但该值的类型Opt所包含的值还包括Opt::AAA, Opt::CCC(i32, u32), Opt::DDD{x: i32, y: u32} 所以不满足匹配条件,无法进行模式匹配。 // 使用if let进行匹配, 忽略集合中没有的值,可进行匹配,并在成功后进行变量绑定
if let Opt::AAA = a {
println!("ok");
}
if let Opt::BBB(x) = b {//x通配u32
println!("x = {}", x); //x = 1
}
if let Opt::CCC(x, y) = c {//x通配i32, y通配u32
println!("x = {}, y = {}", x, y); //x = 1, y = 2
}
if let Opt::DDD { x: n_x, y: n_y } = d {//x通配i32, y通配u32
println!("new_x = {}, new_y = {}", n_x, n_y); //n_x = 1, n_y = 2
} 当” = “左边值的集合是其类型所有值的集合的子集时,可以使用if let或者let else语句来忽略集合中缺少的部分值,以使在匹配失败时进行相应处理。模式串Opt::AAA没有变量作为通配符,所以在匹配成功后不进行变量绑定,模式串Opt::BBB(x) 中,变量x作为通配符匹配所有u32类型的值,可在匹配成功后,对b的值Opt::BBB(1) 进行解构,并将解构得到的值1绑定到变量x。 其它例子在完成rust的变量赋值和模式匹配的理解后,随意编写了几个模式匹配的例子,发现都能通过编译。 let x = 'a';
if let 'a'..='z' | 'A'..='Z' = x {
println!("ok");
}
let x = String::from("hello");
if let "hello" | "world" = x.as_str() {
println!("ok");
}
// if let String::from("hello") | String::from("world") = x { // 模式串中不能进行函数调用
// print!("ok");
// }
let x: [i32; 4] = [1, 2, 3, 4];
if let [1, 2, __, 4] | [5, 6, 7, 8] = x {
println!("ok");
}
if let [1, new_x, 3, 4] | [5, new_x, 7, 8] = x {
println!("new_x = {}", new_x); //new_x = 2
}
if let &[1, 2, 3, 4] | &[2, 3, 4, 5] = &x {
println!("ok");
}
if let 1..=10 | 5..=15 = 10i32 {
println!("ok");
}
if let (x, 1..=10) = (1, 2) {
println!("x = {}", x); // x = 1
}
if let (x, &[2, 4] | &[0, 1]) = (String::from("value"), &[2, 4]) {
println!("x = {:?}", x);// x = "value"
} 由上也可看出符号” __ "其实和变量类似,但只起到了通配符的作用,在匹配成功不进行变量绑定。 |
Beta Was this translation helpful? Give feedback.
-
for 循环那可以加上,下面这个
这也就解释了
或者把这些内容加到 https://course.rs/advance/smart-pointer/deref.html 中 |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
if let是不是还有一种更好记忆的方式, (其实人家已经匹配了所有情况了,只是其余情况都在else里呢,哈哈(✿◡‿◡)) |
Beta Was this translation helpful? Give feedback.
-
请教一下在函数 |
Beta Was this translation helpful? Give feedback.
-
basic/match-pattern/pattern-match
https://course.rs/basic/match-pattern/pattern-match.html
Beta Was this translation helpful? Give feedback.
All reactions