为什么在使用非文字模式时无法访问此匹配模式? [英] Why is this match pattern unreachable when using non-literal patterns?

查看:39
本文介绍了为什么在使用非文字模式时无法访问此匹配模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码(playground)

let max_column = 7;
edge = match current_column {
    0 => Edge::Left,
    max_column => Edge::Right,
    _ => Edge::NotAnEdge
};

导致以下警告:

warning: unreachable pattern
  --> src/main.rs:10:9
   |
9  |         max_column => Edge::Right,
   |         ---------- matches any value
10 |         _ => Edge::NotAnEdge
   |         ^ unreachable pattern
   |
   = note: #[warn(unreachable_patterns)] on by default

用文字替换变量 max_column 工作正常:

Replacing the variable max_column with the literal works fine:

let max_column = 7;
edge = match current_column {
    0 => Edge::Left,
    7 => Edge::Right,
    _ => Edge::NotAnEdge
};

为什么在第一个示例中 _ 无法访问,但对于 current_column != max_column 的任何值都可以访问它?

Why is _ unreachable in the first example when it can be reached for any values where current_column != max_column?

推荐答案

Rust 编程语言 解释了如何处理 match 表达式,重点是我的:

The Rust Programming Language explains how a match expression is processed, emphasis mine:

match 表达式执行时,它将结果值与每个臂的模式进行比较,按顺序.

When the match expression executes, it compares the resulting value against the pattern of each arm, in order.

在您的示例中,max_column 是要绑定到的变量的名称,不是常量或外部变量.当编译器到达 max_column 时,任何剩余的值都将分配给该匹配分支,使后续分支无法访问.

In your example, max_column is the name of the variable to be bound to, not a constant or an outside variable. When the compiler reaches max_column, any remaining values will be assigned to that match arm, making subsequent arms unreachable.

在你的情况下,你想让 max_column 成为一个真正的常量:

In your case, you want to make max_column a real constant:

let current_column = 1;
const MAX_COLUMN: i32 = 7;
edge = match current_column {
    0          => Edge::Left,
    MAX_COLUMN => Edge::Right,
    _          => Edge::NotAnEdge
};

或者如果这不可能,你需要一个比赛守卫:

Or if that's not possible, you want a match guard:

let current_column = 1;
let max_column = 7;
edge = match current_column {
    0                    => Edge::Left,
    a if a == max_column => Edge::Right,
    _                    => Edge::NotAnEdge
};

请注意,作为第一个近似值,a_ 在这种情况下是相同的!在这两种情况下,匹配的变量都将绑定到一个名称(分别为 a_),但任何以 _ 为前缀的标识符都是特殊的 -cased 用作未使用的变量占位符.

Note that, as a first approximation, a and _ are the same thing in this case! In both cases, the matched variable will be bound to a name (a or _ respectively), but any identifier prefixed with _ is special-cased to be used as an unused variable placeholder.

bluss 澄清并修正了这个近似值:

_ 是一个单独的特例,它根本不是一个变量绑定,而是一个没有绑定!与 _x 匹配将值移动到 _x 中,_ 不做这样的事情.(差异是可以观察到的.)

_ is a separate special case, it's not a variable binding at all, but it is the absence of one! Matching against _x moves the value into _x, _ does no such thing. (The difference is observable.)

这篇关于为什么在使用非文字模式时无法访问此匹配模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆