在 Rust 中,可以迭代数组的值:
const COOL_NUMBERS: [i32; 4] = [1, 3, 3, 7];
fn do_something_cool() {
for number in COOL_NUMBERS {
// ...
}
}
但是在
const
环境中是不可能做到的(至少在稳定版上是不可能的):
const COOL_NUMBERS: [i32; 4] = [1, 3, 3, 7];
const fn do_something_cool() {
for number in COOL_NUMBERS {
// ...
}
}
error[E0015]: cannot convert `[i32; 4]` into an iterator in constant functions
--> src/lib.rs:4:19
|
4 | for number in COOL_NUMBERS {
| ^^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
...
请参阅playground 链接以获取完整的错误列表。
我知道可以做这样的事情来避免错误:
const COOL_NUMBERS: [i32; 4] = [1, 3, 3, 7];
const fn do_something_cool() {
do_for_loop(&COOL_NUMBERS)
}
const fn do_for_loop(numbers: &[i32]) {
match numbers {
[] => {}
[number, rest @ ..] => {
// ...
do_for_loop(rest);
}
}
}
但坦白说,这看起来很糟糕,有没有更好的方法?
所以,我的问题是:
是否有更干净的方法来
const
迭代稳定的数组?
至少有一种更干净的方法来
const
迭代不稳定的数组吗?
有任何板条箱可以帮助做到这一点吗?
经过更多搜索后,我发现可以在稳定版中执行此操作:
const COOL_NUMBERS: [i32; 4] = [1, 3, 3, 7];
const fn do_something_cool() {
let mut i = 0;
while i < COOL_NUMBERS.len() {
let number = COOL_NUMBERS[i];
// ...
i += 1;
}
}
如果您需要一个板条箱来使用
const
Iterator
,您可以使用 konst。这是来自 konst docs 的示例:
use konst::iter::{ConstIntoIter, IsIteratorKind};
struct Upto10(u8);
impl ConstIntoIter for Upto10 {
type Kind = IsIteratorKind;
type IntoIter = Self;
type Item = u8;
}
impl Upto10 {
const fn next(mut self) -> Option<(u8, Self)> {
if self.0 < 10 {
let ret = self.0;
self.0 += 1;
Some((ret, self))
} else {
None
}
}
}
const N: u32 = {
let mut n = 0u32;
konst::iter::for_each!{elem in Upto10(7) =>
n = n * 10 + elem as u32;
}
n
};
assert_eq!(N, 789);