Rust中的显式部分数组初始化

brc7rcf0  于 2023-04-06  发布在  其他
关注(0)|答案(2)|浏览(149)

在C中,我可以写int foo[100] = { 7, 8 };,我会得到[7, 8, 0, 0, 0...]
这允许我显式和简洁地为数组开头的一组连续元素选择初始值,其余的元素将被初始化,就像它们有静态存储持续时间一样(即,初始化为适当类型的零值)。
Rust中有等价的吗?

vi4fp9gy

vi4fp9gy1#

据我所知,没有这样的捷径。不过,你确实有几个选择。

直接语法

初始化数组的直接语法适用于Copy类型(整数为Copy):

let array = [0; 1024];

用全0初始化1024个元素的数组。
在此基础上,你可以修改数组:

let array = {
    let mut array = [0; 1024];
    array[0] = 7;
    array[1] = 8;
    array
};
  • 注意使用块表达式将可变性隔离到代码的较小部分的技巧;我们将在下面重复使用它。*
    slice语法

有一个更短的形式,基于clone_from_slice

let array = {
    let mut array = [0; 32];
    
    //  Override beginning of array.
    array[..2].clone_from_slice(&[7, 8]);

    array
};

迭代器语法

还支持从迭代器初始化数组:

let array = {
    let mut array = [0; 1024];

    for (i, element) in array.iter_mut().enumerate().take(2) {
        *element = (i + 7);
    }

    array
};

你甚至可以(可选地)从一个未初始化的状态开始,使用一个unsafe块:

#![feature(maybe_uninit_uninit_array)]

let array = {
    // Create an uninitialized array.
    let mut array: [MaybeUninit<i32>; 10] = MaybeUninit::uninit_array();

    let nonzero = 2;

    for (i, element) in array.iter_mut().enumerate().take(nonzero) {
        // Overwrite `element` without running the destructor of the old value.
        element.write(i + 7)
    }

    for element in array.iter_mut().skip(nonzero) {
        // Overwrite `element` without running the destructor of the old value.
        element.write(0)
    }

    //  Safety:
    //  -   All elements have been initialized.
    unsafe { MaybeUninit::array_assume_init(array) }
};
l3zydbqr

l3zydbqr2#

这里是宏

macro_rules! array {
    ($($v:expr),*) => (
        {
            let mut array = Default::default();
            {
                let mut e = <_ as ::std::convert::AsMut<[_]>>::as_mut(&mut array).iter_mut();
                $(*e.next().unwrap() = $v);*;
            }
            array
        }
    )
}

fn main() {
    let a: [usize; 5] = array!(7, 8);
    assert_eq!([7, 8, 0, 0, 0], a);
}

相关问题