2017-10-15 54 views
1

我想,而不調用它們都匹配多個函數的結果,如果沒有必要:如何在模式匹配時避免多餘的函數調用?

fn foo() -> bool { 
    println!("foo executed"); 
    true 
} 

// I want to do something like this 
// but there is a redundant function call 
match (foo(), foo()) { 
    (false, true) => println!("Bingo!"), 
    _ => println!("Wrong result"), 
} 

// No redundant function call 
// but less impressive and doubling of wrong result processing 
match foo() { 
    false => match foo() { 
     true => println!("Bingo"), 
     _ => println!("Wrong result"), 
    }, 
    _ => println!("Wrong result"), 
} 

我怎樣才能做到這一點?

回答

2

我發現我可以美化與宏觀第二種方法:

macro_rules! lazy_match { 
    (($condition:expr => $expect:pat) => $on_expected:expr, _ => $other:expr) => (
     match $condition { 
      $expect => $on_expected, 
      _ => $other, 
     } 
    ); 
    (
     ($condition:expr => $expect:pat, $($c:expr => $e:pat),+) 
     => $on_expected:expr, _ => $other:expr 
    ) => (
     match $condition { 
      $expect => lazy_match!(($($c => $e),+) => $on_expected, _ => $other), 
      _ => $other, 
     } 
    ); 
} 

lazy_match! { 
    (foo() => false, foo() => true) => println!("Bingo"), 
    _ => println!("Wrong result") 
}; 
3

你可以簡單地做:

if !foo() && foo() { println!("Bingo") } else { println!("Wrong result") } 

的 「和」(&&)和 「或」(||) Rust中的邏輯運算符與大多數語言一樣是短路的。

由於!foo()false,&&的右側將不會被評估,並且foo()將不會被第二次調用。 你的宏解決方案基本上是重新發明短路,至少對於這個玩具的例子(也許它變得更可讀,與您的實際代碼...)。