rust 初始化定长数组的正确方法是什么?

f1tvaqid  于 2022-11-12  发布在  其他
关注(0)|答案(3)|浏览(159)

我在初始化固定长度数组时遇到问题。My attempts so far all result in the same "use of possibly uninitialized variable: foo_array " error
第一个
我实现了Default特征,但是Rust在默认情况下似乎并不像C++构造函数那样调用它。
什么是初始化一个定长数组的正确方法?我想做一个有效的就地初始化,而不是某种复制。
相关:Why is the Copy trait needed for default (struct valued) array initialization?
相关:Is there a way to not have to initialize arrays twice?

q0qdq0h2

q0qdq0h21#

保险箱可是somewhat inefficient solution


# [derive(Copy, Clone, Debug)]

struct Foo {
    a: u32,
    b: u32,
}

fn main() {
    let mut foo_array = [Foo { a: 10, b: 10 }; 10];
}

由于您特别要求a solution without copies

use std::mem::MaybeUninit;

# [derive(Debug)]

struct Foo {
    a: u32,
    b: u32,
}

// We're just implementing Drop to prove there are no unnecessary copies.
impl Drop for Foo {
    fn drop(&mut self) {
        println!("Destructor running for a Foo");
    }
}

pub fn main() {
    let array = {
        // Create an array of uninitialized values.
        let mut array: [MaybeUninit<Foo>; 10] = unsafe { MaybeUninit::uninit().assume_init() };

        for (i, element) in array.iter_mut().enumerate() {
            let foo = Foo { a: i as u32, b: 0 };
            *element = MaybeUninit::new(foo);
        }

        unsafe { std::mem::transmute::<_, [Foo; 10]>(array) }
    };

    for element in array.iter() {
        println!("{:?}", element);
    }
}

MaybeUninit的文档建议这样做。

l7wslrjt

l7wslrjt2#

您可以使用arrayvec crate

载货汽车

[package]
name = "initialize_array"
version = "0.1.0"
edition = "2018"

[dependencies]
arrayvec = "0.7.2"

源代码/main.rs

use arrayvec::ArrayVec; 
use std::iter;

# [derive(Clone)]

struct Foo {
    a: u32,
    b: u32,
}

fn main() {
    let foo_array: [Foo; 10] = iter::repeat(Foo { a: 10, b: 10 })
        .take(10)
        .collect::<ArrayVec<_, 10>>()
        .into_inner()
        .unwrap_or_else(|_| unreachable!());
}
bkkx9g8r

bkkx9g8r3#

最简单的方法是在您的型别上衍生Copy,并以此初始化数组,复制元素N多次:


# [derive(Copy)]

struct Foo {
    a: u32,
    b: u32,
}

let mut foo_array = [Foo { a: 1, b: 2 }; 10];

如果你想避免复制,有几个选择。你可以使用Default特征:

let mut foo_array: [Foo; 10] = Default::default();

但是,这仅限于最多32个元素的数组。使用const泛型,标准库现在可以为 all 数组提供Default。但是,由于正在处理的微妙原因,这将是向后不兼容的更改。
现在,您可以利用const值也可以在数组重复表达式中使用这一事实:

const FOO: Foo = Foo { a: 1, b: 2 };

let mut foo_array = [FOO; 10];

如果您是每晚开机,则可以使用array::map


# ![feature(array_map)]

let mut foo_array = [(); 10].map(|_| Foo::default())

相关问题