for 循环中奇怪的匹配行为

dcx*_*xst 1 rust

Rust菜鸟在这里。我很困惑为什么当我在一个范围内迭代的变量与该范围的最大值匹配时会出现这种奇怪的行为。它不是只匹配最后一项,而是匹配所有内容!有人可以解释一下我从这段代码中得到的输出和编译器警告吗:

fn main() {
  let maxi = 2;
  for i in 0..=maxi {
    match i {
      maxi => {
        println!("i={} matched maxi={}",i,maxi);
      }
      _ => {
        println!("i={} matched with _",i);
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

编译器输出如下

warning: unreachable pattern
 --> se_match_loop.rs:7:15
  |
5 |             maxi => {
  |             ---- matches any value
6 |                 println!("i={} matched maxi={}",i,maxi);
7 |             } _ => {
  |               ^ unreachable pattern
  |
  = note: `#[warn(unreachable_patterns)]` on by default

warning: 1 warning emitted
Run Code Online (Sandbox Code Playgroud)

当我执行编译的脚本时,这是输出

i=0 matched maxi=0
i=1 matched maxi=1
i=2 matched maxi=2
Run Code Online (Sandbox Code Playgroud)

但是如果我声明maxi为常量(用const而不是let),我会得到预期的输出

i=0 matched _
i=1 matched _
i=2 matched maxi=2
Run Code Online (Sandbox Code Playgroud)

Abd*_*P M 7

这记录在匹配命名变量doc.rust-lang.org下。

\n
\n

match启动一个新作用域,在表达式内部声明为模式一部分的变量match将遮蔽匹配结构外部的同名变量,就像所有变量的情况一样。

\n

例如下面的代码

\n
fn main() {\n    let x = Some(5);\n    let y = 10;\n\n    match x {\n        Some(50) => println!("Got 50"),\n        Some(y) => println!("Matched, y = {:?}", y),\n        _ => println!("Default case, x = {:?}", x),\n    }\n\n    println!("at the end: x = {:?}, y = {:?}", x, y);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

将打印

\n
Matched, y = 5\nat the end: x = Some(5), y = 10\n
Run Code Online (Sandbox Code Playgroud)\n
\n

现在让我们考虑你的第一个片段,

\n
fn main() {\n  let maxi = 2;\n  for i in 0..=maxi {\n    match i {\n      maxi => {\n        println!("i={} matched maxi={}",i,maxi);\n      }\n      _ => {\n        println!("i={} matched with _",i);\n      }\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

match你的手臂中的模式引入了一个新的变量(记住match从一个新的范围开始),命名maxi为将匹配任何值。这就是为什么 rust 编译器会在第一个代码片段中发出以下警告。

\n
warning: unreachable pattern\n --> se_match_loop.rs:7:15\n  |\n5 |             maxi => {\n  |             ---- matches any value\n6 |                 println!("i={} matched maxi={}",i,maxi);\n7 |             } _ => {\n  |               ^ unreachable pattern\n  |\n  = note: `#[warn(unreachable_patterns)]` on by default\n\nwarning: 1 warning emitted\n
Run Code Online (Sandbox Code Playgroud)\n

现在让我们考虑第二个(带有const),

\n
fn main() {\n  const maxi: i32 = 2;\n  for i in 0..=maxi {\n    match i {\n      maxi => {\n        println!("i={} matched maxi={}",i,maxi);\n      }\n      _ => {\n        println!("i={} matched with _",i);\n      }\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这将按预期工作,因为常量在任何使用\xe2\x80\x99的地方都会被内联,使得使用它们与简单地用其值替换 的名称相同constdoc.rust-lang.org

\n