在 [false, true] 中迭代的最有效方法是什么?
What is the most efficient way to iterate in [false, true]?
我有一个需要 3 个布尔值的函数 foo
,我想用每个布尔值组合得到这个函数的结果。
我是这样做的:
fn foo(b1: bool, b2: bool, b3: bool) -> bool {
b1 && b2 || !b3
}
fn main() {
for b1 in vec![false, true] {
for b2 in vec![false, true] {
for b3 in vec![false, true] {
println!("{} {} {} -> {}", b1, b2, b3, foo(b1, b2, b3));
}
}
}
}
有没有比创建向量然后遍历它更直接/更短的方法?
有没有一种方法可以使用宏或可变函数来完成,以便编译器只遍历每个案例而不进行迭代?
理想情况下,您应该写 for b1 in [false, true]
,但那是 not yet possible。
即使没有它,您也可以比分配和使用 Vec
做得更好 - 例如,您可以遍历数组切片:
for &b1 in &[false, true] {
for &b2 in &[false, true] {
for &b3 in &[false, true] {
...
请注意,该模式指定了一个引用(取消引用 匹配值)因为遍历 T
的一片不会产生实际的 T
值,但 &T
引用驻留在切片中的值。
要直接迭代固定的少量值,您可以使用 std::iter::once()
和 chain()
:
for b1 in std::iter::once(false).chain(std::iter::once(true)) {
...
上面的内容可以通过(误)使用 Option
来稍微缩短,这也是可迭代的:
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!
:
来节省循环嵌套
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));
}
}
您可以使用 itertools
crate and then use the iproduct!()
宏。
use itertools::iproduct;
fn main() {
const FT: &[bool; 2] = &[false, true];
for (&b1, &b2, &b3) in iproduct!(FT, FT, FT) {
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));
}
}
我有一个需要 3 个布尔值的函数 foo
,我想用每个布尔值组合得到这个函数的结果。
我是这样做的:
fn foo(b1: bool, b2: bool, b3: bool) -> bool {
b1 && b2 || !b3
}
fn main() {
for b1 in vec![false, true] {
for b2 in vec![false, true] {
for b3 in vec![false, true] {
println!("{} {} {} -> {}", b1, b2, b3, foo(b1, b2, b3));
}
}
}
}
有没有比创建向量然后遍历它更直接/更短的方法?
有没有一种方法可以使用宏或可变函数来完成,以便编译器只遍历每个案例而不进行迭代?
理想情况下,您应该写 for b1 in [false, true]
,但那是 not yet possible。
即使没有它,您也可以比分配和使用 Vec
做得更好 - 例如,您可以遍历数组切片:
for &b1 in &[false, true] {
for &b2 in &[false, true] {
for &b3 in &[false, true] {
...
请注意,该模式指定了一个引用(取消引用 匹配值)因为遍历 T
的一片不会产生实际的 T
值,但 &T
引用驻留在切片中的值。
要直接迭代固定的少量值,您可以使用 std::iter::once()
和 chain()
:
for b1 in std::iter::once(false).chain(std::iter::once(true)) {
...
上面的内容可以通过(误)使用 Option
来稍微缩短,这也是可迭代的:
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!
:
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));
}
}
您可以使用 itertools
crate and then use the iproduct!()
宏。
use itertools::iproduct;
fn main() {
const FT: &[bool; 2] = &[false, true];
for (&b1, &b2, &b3) in iproduct!(FT, FT, FT) {
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));
}
}