Rust中显式部分数组初始化

11
在 C 语言中,我可以写 int foo[100] = { 7, 8 }; 来获得 [7, 8, 0, 0, 0...] 数组。
这使我能够明确而简洁地选择一个连续的元素组在数组的开始时的初始值,其余的将被初始化为适当类型的零值,就好像它们具有静态存储期一样。
在 Rust 中是否有相应的功能?
2个回答

13
据我所知,没有这样的捷径。不过,你还有一些选择。

直接语法

使用Copy类型(整数为Copy)初始化数组的直接语法如下:

let array = [0; 1024];

用所有0初始化一个包含1024个元素的数组。

基于此,您随后可以修改该数组:

let array = {
    let mut array = [0; 1024];
    array[0] = 7;
    array[1] = 8;
    array
};

注意使用块表达式将可变性隔离到代码的较小部分的技巧;我们将在下面重复使用它。

切片语法

有一种基于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) }
};

1
@damd:哦,确实有很多变化!我已经更新了答案,停止使用mem::uninitialized(),因为它已经被弃用(而且不安全),并且修复了clone_from_slice片段=>“目标”切片需要与源切片具有完全相同的长度,正如您所指出的那样。 - Matthieu M.

3
这是一个宏。
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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接