繁体   English   中英

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

[英]How to create an array of structs containing large arrays?

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

此代码是一个示例,但未编译

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; 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因为它包含不是CopyBox

好吧,让我们摆脱Box

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

听起来不错吗?

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

Copy非常容易...但是首先我们必须手动实现Clone 天真的方法很有趣,但是很简单:

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

但是, @ FrancisGagné在评论中提醒我, 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);
}

好了, 我们走了


仅对小于32的大小真正起作用的数组有什么处理?

简而言之:Rust还不支持非类型的泛型参数。

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

之所以收到此错误,是因为您尝试使用默认的初始化语法初始化数组,但是您的结构未实现Copy trait,因此这是不允许的。 您可以在此处看到原因,但简而言之,默认的初始化语法将创建您的结构的一个副本,然后尝试将其复制100,000次。 显然,如果您的结构未标记为Copy ,则不允许这样做,因此会引发错误。

通常,可以通过将两个结构都标记为Copy来解决此问题,如下所示:

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

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

但是,您会注意到它仍然无法编译,因为您实际上没有数组。 您实际上已将类型用于切片( 请看一下类似的问题 )。 实现Copy ,使你的代码不能编译,因为_TmoveP结构只能得到Copy ,如果所有的字段都Copy

目前尚不清楚数组是否将始终具有固定大小。 如果可以,则需要使用类型[T; N] [T; N] ,其中T是您的类型, N是元素的数量(例如[i32; 300] )。 如果不是,则需要Vec<T>

如果使用数组,则会遇到另一个问题 阵列实现Copy (最多32个),而不是Clone ,我们需要实现Clone_TmoveP之前,我们就可以实现Copy 因此,让我们自己做:

impl Clone for _TmoveP {
    fn clone(&self) -> _TmoveP {
        _TmoveP {
            data4: self.data4,
            data5: self.data5
        }
    }
}

然后,您可以从_TmoveP删除#[derive(Clone)] (仅保留Copy ),我们终于找到了一个_TmoveP解决方案! 是我的解决方案的游乐场链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM