在 Rust 中定义常量数组时,有没有办法使用闭包或列表理解?假设我们有这三个常量数组:
const K1 : [i32;8] = [100, 100, 101, 102, 104, 106, 108, 900];
const K2 : [i32;8] = [-100, -100, -101, -102, -104, -106, -108, -900];
const K3 : [i32;8] = [-900, -108, -106, -104, -102, -101, -100, -100];
Run Code Online (Sandbox Code Playgroud)
在Python中K2和K3可以表示为
K2=[-x for x in K1]
K3=[-x for x in K1[::-1]
Run Code Online (Sandbox Code Playgroud)
Rust 有一个可爱的板条箱,可以模拟 python 列表理解,但我不认为它可以用来定义常量。那么有没有比上面简单地输入 K2 和 K3 更优雅的解决方案呢?
有一天,当 Rust 具有更多的持续评估能力时,我们也许可以编写以下内容:
\nconst K1: [i32; 8] = [100, 100, 101, 102, 104, 106, 108, 900];\nconst K2: [i32; 8] = K1.map(|x| -x);\nconst K3: [i32; 8] = { let mut a = K2; a.reverse(); a };\n
Run Code Online (Sandbox Code Playgroud)\n但是,目前s 和 sarray::map()
都不slice::reverse()
是const fn
,因此您不能在常量中使用它们。map
特别是会更麻烦,因为它需要定义高阶 const fns 的能力,但目前尚不可用。
但是,我们可以定义自己的const
函数来完成我们需要的特定工作。这需要更多的代码,因此如果您只有一种情况,这不是一个好主意,但无论如何它可能是值得的,以帮助常量定义的可读性,或者如果这些情况出现多次。
const K1: [i32; 8] = [100, 100, 101, 102, 104, 106, 108, 900];\nconst K2: [i32; 8] = array_i32_mul(-1, K1);\nconst K3: [i32; 8] = array_reverse(K2);\n\nconst fn array_i32_mul<const N: usize>(factor: i32, mut a: [i32; N]) -> [i32; N] {\n let mut i = 0;\n while i < N {\n a[i] *= factor;\n i += 1;\n }\n a\n}\n\nconst fn array_reverse<T: Copy, const N: usize>(mut a: [T; N]) -> [T; N] {\n let mut i = 0;\n while i < N / 2 {\n let from_end = N - i - 1;\n (a[i], a[from_end]) = (a[from_end], a[i]);\n i += 1;\n }\n a\n}\n\nfn main() {\n dbg!(K1, K2, K3);\n}\n
Run Code Online (Sandbox Code Playgroud)\n笔记:
\nfor
在 s 中使用循环const fn
,因为不支持特征并且for
使用Iterator
的是特征,所以我们必须用于while
所有索引。array_reverse
不需要T: Copy
if std::mem::swap()
were const,但现在还不需要。正如另一个答案中所建议的,与使用相比,进行这项工作的优点Lazy
是:
Lazy
只能在运行时访问该值的情况。