#array #literals #gods

ary

神之数组字面量

1 个不稳定版本

0.1.0 2022年11月24日

#54#literals

Apache-2.0

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; _],
];

无运行时依赖