const 对数组值的迭代

问题描述 投票:0回答:1

在 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);
        }
    }
}

但坦白说,这看起来很糟糕,有没有更好的方法?

所以,我的问题是:

  1. 是否有更干净的方法来

    const
    迭代稳定的数组?

  2. 至少有一种更干净的方法来

    const
    迭代不稳定的数组吗?

  3. 有任何板条箱可以帮助做到这一点吗?

rust compile-time
1个回答
2
投票

经过更多搜索后,我发现可以在稳定版中执行此操作:

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);
© www.soinside.com 2019 - 2024. All rights reserved.