It might be easier to understand what's going on by looking at the compiler's warnings:
warning: unused variable: `from`
--> src/main.rs:12:9
|
12 | from => println!("1"),
| ^^^^
|
= note: #[warn(unused_variables)] on by default
warning: unreachable pattern
--> src/main.rs:13:9
|
13 | to => println!("2"),
| ^^ this is an unreachable pattern
|
= note: #[warn(unreachable_patterns)] on by default
note: this pattern matches any value
--> src/main.rs:12:9
|
12 | from => println!("1"),
| ^^^^
warning: unused variable: `to`
--> src/main.rs:13:9
|
13 | to => println!("2"),
| ^^
|
= note: #[warn(unused_variables)] on by default
warning: unreachable pattern
--> src/main.rs:14:9
|
14 | _ => println!("other"),
| ^ this is an unreachable pattern
|
= note: #[warn(unreachable_patterns)] on by default
note: this pattern matches any value
--> src/main.rs:12:9
|
12 | from => println!("1"),
| ^^^^
Basically, the identifiers from and to do not refer to the values contained in the bindings. They are new bindings that happen to match anything. The same thing happens with new identifier names:
match i {
x => println!("1"),
y => println!("2"),
_ => println!("other"),
}
Since the program always matches the first case, "1" is always printed.
You can get the expected result by declaring from and to as const:
const from: NodeIndex = NodeIndex(21030);
const to: NodeIndex = NodeIndex(21031);
Or by using object literals directly:
match i {
NodeIndex(21030) => println!("1"),
NodeIndex(21031) => println!("2"),
_ => println!("other"),
}
If the values of from and to are only known in runtime, you can use if/else statements:
if n == from {
println!("1");
} else if n == to {
println!("2");
} else {
println!("other");
}
... or add if clauses during the match (which are evaluated in run-time):
match i {
n if n == from => println!("1"),
n if n == to => println!("2"),
_ => println!("other"),
}