arrays - 如何创建包含大型数组的结构体数组?

标签 arrays struct rust

如何创建包含固定大小的大数组的结构数组?我想使用数组而不是向量。

此代码是示例,但无法编译

struct _Tmove {
    data1: usize,
    data2: u64,
    data3: bool,
}

struct _TmoveP {
    data4: Box<[_Tmove]>,
    data5: isize,
}

fn main() {
    let mut gen_list = Box::new([
        _TmoveP {
            data5: 1,
            data4: Box::new([_Tmove { data1: 5, data2: 1, data3: true }; 300]),
        }
        ; 100000]);

    assert!(gen_list[0].data4[0].data1==5);
}
error[E0277]: the trait bound `_Tmove: std::marker::Copy` is not satisfied
--> src/main.rs:16:29
       |
    16 |             data4: Box::new([_Tmove { data1: 5, data2: 1, data3: true }; 300]),
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the `Copy` trait is required because the repeated element will be copied

error[E0277]: the trait bound `_TmoveP: std::marker::Copy` is not     satisfied
--> src/main.rs:13:33
    |
13  |     let mut gen_list = Box::new([
    |                                 ^
    |
    = note: the `Copy` trait is required because the repeated element will be copied

我正在使用 Rust 1.12。

最佳答案

为了受益于初始化语法:[expr; N]expr的结果需要Copy(因为需要进行复制)。

#[derive(Copy, Clone)]
struct _Tmove {
    data1: usize,
    data2: u64,
    data3: bool,
}

#[derive(Copy, Clone)]
struct _TmoveP {
    data4: Box<[_Tmove]>,
    data5: isize,
}

但是,在这种情况下,_TmoveP 不能Copy,因为它包含一个Box,但它不是复制

好吧,让我们摆脱 Box:

#[derive(Copy, Clone)]
struct _TmoveP {
    data4: [_Tmove; 300],
    data5: isize,
}

听起来不错吗?

但不幸的是,[_Tmove; 300] 也不是 Clone :( 不幸的是,我们遇到了 Rust 编译器的限制(它适用于大小小于 32 的情况)。

复制非常简单...但首先我们必须手动实现克隆。这种幼稚的方式并不有趣,但它很简单:

impl Clone for _TmoveP {
    fn clone(&self) -> _TmoveP {
        unsafe {
            let mut res = _TmoveP {
                data4: std::mem::uninitialized(),
                data5: self.data5,
            };

            std::ptr::copy_nonoverlapping(
                &self.data4 as *const _Tmove,
                std::mem::transmute(&mut res.data4),
                300
            );

            res
        }
    }
}

注意:由于某种原因 &mut res.data4 as *mut _ 无法编译...无论如何:x

但是,@Francis Gagné在评论中提醒我,Copy 类型有一个奇怪的技巧:

impl Clone for _TmoveP {
    fn clone(&self) -> _TmoveP { *self }
}

由于某种原因,这种方法有效,并且在这些情况下很方便。

最后,这有效了...哦等等,main 中有一个问题!

fn main() {
    let gen_list = Box::new([
        _TmoveP {
            data5: 1,
            data4: [_Tmove { data1: 5, data2: 1, data3: true }; 300],
        }
        ; 100000]);

    assert!(gen_list[0].data4[0].data1==5);
}

好的,here we go .


仅适用于小于 32 的数组是怎么回事?

简单地说:Rust(还?)不支持非类型泛型参数。

数组在某种程度上是特殊情况,但需要独立实现每个大小的特征...因此标准库为最大大小为 32 的数组实现其特征,因为这似乎是一个很好的权衡。

关于arrays - 如何创建包含大型数组的结构体数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39924909/

相关文章:

javascript - 查找两个数组之间的差异

c - 在字符数组上使用 printf 返回垃圾和字符串

rust - 如何从文字字节表达式构造 const 整数?

rust - 使用 cargo 时如何获取带有调试信息的发布版本?

rust - 如何对具有泛型类型参数的特征进行装箱?

java - 在 Java 中存储和访问字符串(通过使用数组)

arrays - 删除数组元素的最快方法是什么?

c++ - 如何将不同大小的数组传递给我的 C++ 函数?

c++ - 接受用户输入的字符并按出现的降序显示它们的程序

c - 初始化一个具有结构体的队列