初始化固定长度数组的正确方法是什么? [英] What is the proper way to initialize a fixed length array?

查看:17
本文介绍了初始化固定长度数组的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在初始化固定长度数组时遇到问题.到目前为止我的尝试都导致相同的使用可能未初始化的变量:foo_array"错误:

I'm having trouble initializing a fixed length array. My attempts so far all result in the same "use of possibly uninitialized variable: foo_array" error:

#[derive(Debug)]
struct Foo { a: u32, b: u32 }

impl Default for Foo {
    fn default() -> Foo { Foo{a:1, b:2} }
}

pub fn main() {
    let mut foo_array: [Foo; 10];

    // Do something here to in-place initialize foo_array?

    for f in foo_array.iter() {
        println!("{:?}", f);
    }
}

error[E0381]: use of possibly uninitialized variable: `foo_array`
  --> src/main.rs:13:14
   |
13 |     for f in foo_array.iter() {
   |              ^^^^^^^^^ use of possibly uninitialized `foo_array`

我实现了 Default trait,但 Rust 似乎并没有像 C++ 构造函数那样默认调用它.

I implemented the Default trait, but Rust does not seem to call this by default akin to a C++ constructor.

初始化固定长度数组的正确方法是什么?我想做一个高效的就地初始化,而不是某种复制.

What is the proper way to initialize a fixed length array? I'd like to do an efficient in-place initialization rather than some sort of copy.

相关:为什么默认(结构值)数组初始化所需的复制特征?

相关:有没有办法不必两次初始化数组?

推荐答案

The safe but 有点低效的解决方案:

The safe but 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];
}

因为您特别要求 没有副本的解决方案:

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 的文档.

This is recommended by the documentation of MaybeUninit.

这篇关于初始化固定长度数组的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆