Rust 为什么PartialEq/Eq工作正常时match不工作?

Rust 为什么PartialEq/Eq工作正常时match不工作?,rust,Rust,我有一个简单的代码: #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)] struct NodeIndex(u32); fn main() { let i = NodeIndex(5323); let from = NodeIndex(21030); let to = NodeIndex(21031); println!("from == i => {}, to ==

我有一个简单的代码:

#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
struct NodeIndex(u32);

fn main() {
    let i = NodeIndex(5323);
    let from = NodeIndex(21030);
    let to = NodeIndex(21031);

    println!("from == i => {}, to == i => {}", from == i, to == i);

    match i {
        from => println!("1"),
        to => println!("2"),
        _ => println!("other"),
    }
}
它打印:

from==i=>false,to==i=>false
1.
所以
i!=从
i!=到
,但匹配调用from=>println!(“1”),,
发生了什么?

查看编译器的警告可能更容易理解发生了什么:

警告:未使用的变量:`from`
-->src/main.rs:12:9
|
12 | from=>println!("1"),
|         ^^^^
|
=注意:#[警告(未使用的_变量)]默认打开
警告:无法访问的模式
-->src/main.rs:13:9
|
13 | to=>println!("2"),
|^^这是一种无法达到的模式
|
=注意:#[警告(无法访问的_模式)]默认打开
注意:此模式匹配任何值
-->src/main.rs:12:9
|
12 | from=>println!("1"),
|         ^^^^
警告:未使用的变量:`to`
-->src/main.rs:13:9
|
13 | to=>println!("2"),
|         ^^
|
=注意:#[警告(未使用的_变量)]默认打开
警告:无法访问的模式
-->src/main.rs:14:9
|
14 |=>println!(“其他”),
|^这是一个无法访问的模式
|
=注意:#[警告(无法访问的_模式)]默认打开
注意:此模式匹配任何值
-->src/main.rs:12:9
|
12 | from=>println!("1"),
|         ^^^^
基本上,从到的标识符
不引用绑定中包含的值。它们是新绑定,恰好匹配任何内容。新的标识符名称也会发生同样的情况:

match i {
    x => println!("1"),
    y => println!("2"),
    _ => println!("other"),
}
由于程序始终匹配第一个案例,因此始终打印“1”

通过将
from
to
声明为
const
,可以获得预期的结果:

const from: NodeIndex = NodeIndex(21030);
const to: NodeIndex = NodeIndex(21031);
或者直接使用对象文字:

match i {
    NodeIndex(21030) => println!("1"),
    NodeIndex(21031) => println!("2"),
    _ => println!("other"),
}
如果
from
to
的值仅在运行时已知,则可以使用
If
/
else
语句:

if n == from {
    println!("1");
} else if n == to {
    println!("2");
} else {
    println!("other");
}
。。。或者在匹配过程中添加
if
子句(在运行时进行评估):


查看编译器的警告可能更容易理解发生了什么:

警告:未使用的变量:`from`
-->src/main.rs:12:9
|
12 | from=>println!("1"),
|         ^^^^
|
=注意:#[警告(未使用的_变量)]默认打开
警告:无法访问的模式
-->src/main.rs:13:9
|
13 | to=>println!("2"),
|^^这是一种无法达到的模式
|
=注意:#[警告(无法访问的_模式)]默认打开
注意:此模式匹配任何值
-->src/main.rs:12:9
|
12 | from=>println!("1"),
|         ^^^^
警告:未使用的变量:`to`
-->src/main.rs:13:9
|
13 | to=>println!("2"),
|         ^^
|
=注意:#[警告(未使用的_变量)]默认打开
警告:无法访问的模式
-->src/main.rs:14:9
|
14 |=>println!(“其他”),
|^这是一个无法访问的模式
|
=注意:#[警告(无法访问的_模式)]默认打开
注意:此模式匹配任何值
-->src/main.rs:12:9
|
12 | from=>println!("1"),
|         ^^^^
基本上,从
到的标识符
不引用绑定中包含的值。它们是新绑定,恰好匹配任何内容。新的标识符名称也会发生同样的情况:

match i {
    x => println!("1"),
    y => println!("2"),
    _ => println!("other"),
}
由于程序始终匹配第一个案例,因此始终打印“1”

通过将
from
to
声明为
const
,可以获得预期的结果:

const from: NodeIndex = NodeIndex(21030);
const to: NodeIndex = NodeIndex(21031);
或者直接使用对象文字:

match i {
    NodeIndex(21030) => println!("1"),
    NodeIndex(21031) => println!("2"),
    _ => println!("other"),
}
如果
from
to
的值仅在运行时已知,则可以使用
If
/
else
语句:

if n == from {
    println!("1");
} else if n == to {
    println!("2");
} else {
    println!("other");
}
。。。或者在匹配过程中添加
if
子句(在运行时进行评估):


我认为您只能将match与literal一起使用。做你想做的。我认为你只能用文字匹配。谢谢,实际上我不能使用
const
,因为我在实际程序中计算这些值,所以我必须使用
if-else
在这种情况下?@user1244932,你可以使用
匹配I{x if x==v1=>,x if x==v2=>,}
syntax@user1244932我已经更新了答案。实际上,您可以使用if/else或将
if
子句添加到匹配案例中。谢谢,实际上我不能使用
const
,因为我在实际程序中计算这些值,所以我必须使用
if-else
在这种情况下?@user1244932,您可以使用
匹配I{x if x==v1=>,x if x==v2=>,}
syntax@user1244932我已经更新了答案。实际上,您可以使用if/else或将
if
子句添加到匹配案例中。