From 8f1121ab45de3b99162b7c2c9e835246b59cba04 Mon Sep 17 00:00:00 2001 From: sunface Date: Tue, 1 Mar 2022 20:55:22 +0800 Subject: [PATCH] add patterns.md --- src/pattern-match/patterns.md | 77 +++++++++++++++++++++- zh-CN/src/pattern-match/patterns.md | 99 ++++++++++++++++++++++++++++- 2 files changed, 174 insertions(+), 2 deletions(-) diff --git a/src/pattern-match/patterns.md b/src/pattern-match/patterns.md index c3f49b9..2b2d752 100644 --- a/src/pattern-match/patterns.md +++ b/src/pattern-match/patterns.md @@ -1,6 +1,6 @@ # Patterns -🌟🌟 Using `|` to match several values. +🌟🌟 use `|` to match several values, use `..=` to match a inclusive range ```rust,editable fn main() {} @@ -21,3 +21,78 @@ fn match_number(n: i32) { } ``` +🌟🌟🌟 The `@` operator lets us create a variable that holds a value at the same time we are testing that value to see whether it matches a pattern. +```rust,editable + +struct Point { + x: i32, + y: i32, +} + +fn main() { + // fill in the blank to let p match the second arm + let p = Point { x: __, y: __ }; + + match p { + Point { x, y: 0 } => println!("On the x axis at {}", x), + // second arm + Point { x: 0..=5, y: y@ (10 | 20 | 30) } => println!("On the y axis at {}", y), + Point { x, y } => println!("On neither axis: ({}, {})", x, y), + } +} +``` + +🌟🌟🌟 + +```rust,editable + +// fix the errors +enum Message { + Hello { id: i32 }, +} + +fn main() { + let msg = Message::Hello { id: 5 }; + + match msg { + Message::Hello { + id: 3..=7, + } => println!("Found an id in range [3, 7]: {}", id), + Message::Hello { id: newid@10 | 11 | 12 } => { + println!("Found an id in another range [10, 12]: {}", newid) + } + Message::Hello { id } => println!("Found some other id: {}", id), + } +} +``` + +🌟🌟 A match guard is an additional if condition specified after the pattern in a match arm that must also match, along with the pattern matching, for that arm to be chosen. +```rust,editable + +// fill in the blank to make the code work, `split` MUST be used +fn main() { + let num = Some(4); + let split = 5; + match num { + Some(x) __ => assert!(x < split), + Some(x) => assert!(x >= split), + None => (), + } +} +``` + +🌟🌟 Ignoring remaining parts of the value with `..` +```rust,editable + +// fill the blank to make the code work +fn main() { + let numbers = (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048); + + match numbers { + __ => { + assert_eq!(first, 2); + assert_eq!(last, 2048); + } + } +} +``` \ No newline at end of file diff --git a/zh-CN/src/pattern-match/patterns.md b/zh-CN/src/pattern-match/patterns.md index 3c9daa3..0894345 100644 --- a/zh-CN/src/pattern-match/patterns.md +++ b/zh-CN/src/pattern-match/patterns.md @@ -1 +1,98 @@ -# Patterns +# 模式 + +🌟🌟 使用 `|` 可以匹配多个值, 而使用 `..=` 可以匹配一个闭区间的数值序列 +```rust,editable + +fn main() {} +fn match_number(n: i32) { + match n { + // 匹配一个单独的值 + 1 => println!("One!"), + // 使用 `|` 填空,不要使用 `..` 或 `..=` + __ => println!("match 2 -> 5"), + // 匹配一个闭区间的数值序列 + 6..=10 => { + println!("match 6 -> 10") + }, + _ => { + println!("match 11 -> +infinite") + } + } +} +``` + +🌟🌟🌟 `@` 操作符可以让我们将一个与模式相匹配的值绑定到新的变量上 +```rust,editable + +struct Point { + x: i32, + y: i32, +} + +fn main() { + // 填空,让 p 匹配第二个分支 + let p = Point { x: __, y: __ }; + + match p { + Point { x, y: 0 } => println!("On the x axis at {}", x), + // 第二个分支 + Point { x: 0..=5, y: y@ (10 | 20 | 30) } => println!("On the y axis at {}", y), + Point { x, y } => println!("On neither axis: ({}, {})", x, y), + } +} +``` + +🌟🌟🌟 + +```rust,editable + +// 修复错误 +enum Message { + Hello { id: i32 }, +} + +fn main() { + let msg = Message::Hello { id: 5 }; + + match msg { + Message::Hello { + id: 3..=7, + } => println!("id 值的范围在 [3, 7] 之间: {}", id), + Message::Hello { id: newid@10 | 11 | 12 } => { + println!("id 值的范围在 [10, 12] 之间: {}", newid) + } + Message::Hello { id } => println!("Found some other id: {}", id), + } +} +``` + +🌟🌟 匹配守卫(match guard)是一个位于 match 分支模式之后的额外 if 条件,它能为分支模式提供更进一步的匹配条件。 +```rust,editable + +// 填空让代码工作,必须使用 `split` +fn main() { + let num = Some(4); + let split = 5; + match num { + Some(x) __ => assert!(x < split), + Some(x) => assert!(x >= split), + None => (), + } +} +``` + +🌟🌟🌟 使用 `..` 忽略一部分值 +```rust,editable + +// 填空,让代码工作 +fn main() { + let numbers = (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048); + + match numbers { + __ => { + assert_eq!(first, 2); + assert_eq!(last, 2048); + } + } +} +``` \ No newline at end of file