Rust 在[false,true]中迭代最有效的方法是什么?

Rust 在[false,true]中迭代最有效的方法是什么?,rust,boolean,iteration,combinations,Rust,Boolean,Iteration,Combinations,我有一个函数foo,它需要3个布尔值,我想用每个布尔值的组合得到这个函数的结果 我是这样做的: fn-foo(b1:bool,b2:bool,b3:bool)->bool{ b1和b2||!b3 } fn main(){ 对于vec中的b1![假,真]{ 对于vec中的b2![假,真]{ 对于vec中的b3![假,真]{ println!(“{}{}{}->{}”,b1,b2,b3,foo(b1,b2,b3)); } } } } 有没有比创建一个向量然后遍历它更直接/更短的方法 有没有一种方法

我有一个函数
foo
,它需要3个布尔值,我想用每个布尔值的组合得到这个函数的结果

我是这样做的:

fn-foo(b1:bool,b2:bool,b3:bool)->bool{
b1和b2||!b3
}
fn main(){
对于vec中的b1![假,真]{
对于vec中的b2![假,真]{
对于vec中的b3![假,真]{
println!(“{}{}{}->{}”,b1,b2,b3,foo(b1,b2,b3));
}
}
}
}
有没有比创建一个向量然后遍历它更直接/更短的方法


有没有一种方法可以使用宏或可变函数来实现这一点,这样编译器只需遍历每种情况而无需进行迭代?

理想情况下,您可以在[false,true]中为b1编写
,但这就是问题所在

即使没有它,您也可以比分配和使用
Vec
做得更好-例如,您可以迭代数组切片:

for &b1 in &[false, true] {
    for &b2 in &[false, true] {
        for &b3 in &[false, true] {
            ...
请注意,该模式指定了一个引用(它取消了对匹配值的引用),因为在
T
切片上迭代不会产生实际的
T
值,而是
&T
引用驻留在切片中的值

要直接迭代固定的少量值,可以使用
std::iter::once()
chain()

通过(mis)使用
选项
,上述内容可以稍微缩短,这也是可行的:

for b1 in Some(false).into_iter().chain(Some(true)) {
    ...

至少可以使用数组而不是向量,从而保存动态分配:

fn foo(b1: bool, b2: bool, b3: bool) -> bool {
  b1 && b2 || !b3
}

fn main() {
  for b1 in &[false, true] {
    for b2 in &[false, true] {
      for b3 in &[false, true] {
        println!("{} {} {} -> {}", 
                 b1, b2, b3,
                 foo(*b1, *b2, *b3));
      }
    }
  }
}
然后,您可以使用以下方法保存循环嵌套:

您可以使用板条箱,然后使用宏

使用itertools::iproduct;
fn main(){
常数FT:&[bool;2]=&[false,true];
用于IPProduct!(英尺、英尺、英尺)中的(&b1、b2和b3){
println!(“{}{}{}->{}”,b1,b2,b3,foo(b1,b2,b3));
}
}

不是说它“更高效”,而是写起来更短。

没有必要把事情复杂化。您只需执行以下操作:

fn main() {
    for i in 0..=0b111 {
        let a = (i & 1) == 1;
        let b = (i >> 1 & 1) == 1;
        let c = (i >> 2 & 1) == 1;
        println!("{} {} {} -> {}", a, b, c, foo(a, b, c));
    }
}

要么我是盲人,要么你的答案在我发布我的答案时没有包括
itertools
。如果是这样,我会很高兴地删除我的答案:)@vallentin我想我在你写作的时候编辑了它,我也在想同样的事情,但我可能会使用
let a=(I&1)!=0; 设b=(i&2)=0; 设c=(i&4)!=0;这使得cealr第一种情况在某种程度上并不特殊。我想你同样可以把第一个写成
让a=(I>>0&1)==1我不确定这是如何比原始代码简单-它要求读者研究单个位操作,甚至理解代码试图做什么!原文可能不那么聪明,但肯定更简单,更容易理解。我想这取决于你的背景。我发现这个答案比原来的答案更简单,更不容易出错,因为它涉及的重复和嵌套更少。很好的低级解决方案!它在数学上不太令人满意,但它是可扩展的,高效的,并且不需要板条箱
use itertools::iproduct; // 0.9.0

fn foo(b1: bool, b2: bool, b3: bool) -> bool {
  b1 && b2 || !b3
}

fn main() {
  for (&b1, &b2, &b3) in iproduct!(&[false, true], &[false, true], &[false, true]) {
    println!("{} {} {} -> {}", 
             b1, b2, b3,
             foo(b1, b2, b3));
  }
}
fn main() {
    for i in 0..=0b111 {
        let a = (i & 1) == 1;
        let b = (i >> 1 & 1) == 1;
        let c = (i >> 2 & 1) == 1;
        println!("{} {} {} -> {}", a, b, c, foo(a, b, c));
    }
}