2017-07-03 59 views
0

我有這個簡單的代碼:爲什麼在PartialEq/Eq正常工作時匹配不起作用?

#[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 != fromi != to,但match通話from => println!("1"),, 是怎麼回事?

+0

我認爲你可以使用匹配只能用文字。 – Boiethios

+1

[This code](https://play.rust-lang.org/?gist=33255e4b59d8c42cf6bb73a42da829bb&version=stable&backtrace=0)可以做你想做的事情。 – red75prime

回答

6

可能更容易理解發生了什麼事情通過查看編譯器的警告:

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"), 
    |   ^^^^ 

基本上標識符fromto是指包含在綁定的值。它們是新的恰巧匹配任何東西的綁定。同樣的事情發生了新的標識符名稱:

match i { 
    x => println!("1"), 
    y => println!("2"), 
    _ => println!("other"), 
} 

由於程序總是第一個匹配的情況下,始終印有「1」。

可以通過聲明fromtoconst得到預期的結果:

const from: NodeIndex = NodeIndex(21030); 
const to: NodeIndex = NodeIndex(21031); 

,或者直接使用對象文本:

match i { 
    NodeIndex(21030) => println!("1"), 
    NodeIndex(21031) => println!("2"), 
    _ => println!("other"), 
} 

如果fromto值中唯一已知運行時,您可以使用if/else語句:

比賽(在運行時計算)時項
if n == from { 
    println!("1"); 
} else if n == to { 
    println!("2"); 
} else { 
    println!("other"); 
} 

...或添加if條款:

match i { 
    n if n == from => println!("1"), 
    n if n == to => println!("2"), 
    _ => println!("other"), 
} 
+0

謝謝,實際上我不能使用'const',因爲我在真實程序中計算這些值,所以在這種情況下我必須使用'if else'? – user1244932

+0

@ user1244932,你可以使用'match i {x if x == v1 => ...,x if x == v2 => ...,}'語法 – red75prime

+0

@ user1244932我已經更新了答案。事實上,你可以使用if/else或在匹配情況下添加if語句。 –