如何初始化常量泛型数组?

Leg*_*ast 3 generics rust const-generics

我正在尝试更多地了解 const 泛型以及它们如何应用于任何维度的某些网格算法。下面是一个片段 - 如何创建一个 const 泛型参数大小的数组?

type Point<const N: usize> = [i32; N];

fn new_point<const N: usize>(x: i32, y: i32) -> Point<N> {
    [x, y]
}

fn main() {
    let point: Point<2> = new_point(1, 2);
    println!("Point: {:?}", point)
}
Run Code Online (Sandbox Code Playgroud)

上面的结果会导致编译器错误:

error[E0308]: mismatched types
 --> src/main.rs:4:5
  |
3 | fn new_point<const N: usize>(x: i32, y: i32) -> Point<N> {
  |                                                 -------- expected `[i32; N]` because of return type
4 |     [x, y]
  |     ^^^^^^ expected `N`, found `2_usize`
  |
  = note: expected array `[i32; N]`
             found array `[i32; 2]`
Run Code Online (Sandbox Code Playgroud)

请注意,我并不是在寻找使用Vec<N>. 如何用一些值初始化这个通用数组?

Kev*_*eid 6

以下是构造任意长度数组的一些方法。

  • 您可以使用std::array::from_fn它将允许从计算其元素的函数构造任意大小的数组:

    /// Constructs an array with the first two elements being x and y.
    fn new_point<const N: usize>(x: i32, y: i32) -> Point<N> {
        std::array::from_fn(|i| {
            match i {
                0 => x,
                1 => y,
                _ => 0,
            }
        })
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以使用单个值的副本构造一个数组:

    [0; N]
    
    // or
    [foo(); N]
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以构造一个数组,然后对其进行变异:

    fn new_point<const N: usize>(x: i32, y: i32) -> Point<N> {
        let mut array = [0; N];
        if N > 0 {
            array[0] = x;
        }
        if N > 1 {
            array[1] = y;
        }
        array
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以通过从另一个数组 ping 来构造一个数组map(这过去是作为缺少 的解决方法来完成的from_fn()):

    let mut i = 0;
    [(); N].map(|()| {
        i += 1;
        i
    }]
    
    Run Code Online (Sandbox Code Playgroud)
  • .try_into()您可以通过使用转换切片或向量来构造数组;如果切片或向量的长度不正确,转换将失败。查看的实现者TryFrom列表,并查找那些说 的实现者... for [T; N]