1 个不稳定版本
0.1.0 | 2022年11月24日 |
---|
#54 在 #literals
20KB
314 行
ary
- 神之数组字面量。
Rust提供了两种数组字面量的语法:[a, b, c]
和 [x; count]
。在构建复杂的 const
数组时,仅有这两种形式可能会相当受限。
此库提供了一个 ary![]
宏来改善这种情况。
数组展开
首先,我们允许元素表达式以 in
开头,表示它应该展开到整个数组中。该表达式必须是一个 const
数组或切片。例如
const MACRO: &[u8] = b"ary![]";
assert_eq!(&ary![0x3a, 0x3a, in MACRO, 0x3b], b"::ary![];");
assert_eq!(&ary![in b"ary![]"; 3], b"ary![]ary![]ary![]");
注意,因为这个可以是任何 const
表达式,我们可以轻松构建不同大小的数组。
const fn make_slice() -> &'static [u8] {
// ...
}
const WORDS: &[u8] = &ary![in make_slice(); 3];
assert_eq!(WORDS.len() % 3, 0);
范围修饰符
在所有元素之后,可以通过在 =>
符号后放置范围值对来指定构建数组范围的范围修饰符。
const ARRAY: &[i32] = &ary![0; 32 =>
5..10: |i| !(i as i32), // Closure is called once for each index.
10.._: [1, 2, 3], // Upper bound of range can be inferred.
14..=17: [-1; _], // Length of a Rust array literal can be inferred.
29..: [-2, -2, -2], // Unbounded ranges work too.
31: 42, // Single elements can be set directly.
(1 + 1): 2, // Complex index expressions must be wrapped in parens to
// avoid a syntax ambiguity.
];
assert_eq!(ARRAY, &[
0, 0, 2, 0, 0, -6, -7, -8, -9, -10, 1, 2, 3, 0, -1, -1,
-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, 42,
]);
// You can use .. to replace the contents of the whole array.
const RANGE: &[i32] = &ary![0; 9 => ..: |i| i as i32 + 1];
assert_eq!(RANGE, &[1, 2, 3, 4, 5, 6, 7, 8, 9]);
从范围推断数组长度
可以跳过元素表达式并继续使用范围修饰符;在这种情况下,数组的尺寸将从提供的修饰符的上限中推断出来。
const EVENS: [usize; 8] = ary![=> ..8: |i| i * 2];
assert_eq!(EVENS, [0, 2, 4, 6, 8, 10, 12, 14]);
// Unbounded ranges do not contribute to the inferred size.
const EMPTY: [i32; 0] = ary![=> ..: |_| unreachable!()];
// Lower bounds of unbounded-above ranges *do* contribute, though.
const NONEMPTY: [i32; 10] = ary![=>
..: [42; _],
10..: [-1; _],
];