2017-10-15 56 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()将不会被第二次调用。 你的宏解决方案基本上是重新发明短路,至少对于这个玩具的例子(也许它变得更可读,与您的实际代码...)。