首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用宏初始化大量非复制元素

使用宏初始化大量非复制元素
EN

Stack Overflow用户
提问于 2016-03-28 16:09:48
回答 1查看 1.8K关注 0票数 4

我正在尝试用相同的初始化器初始化一个很大的元素数组。64个元素只是一个例子--我希望它至少是16k。不幸的是,一个简单的

代码语言:javascript
复制
let array : [AllocatedMemory<u8>; 64] = [AllocatedMemory::<u8>{mem:&mut []};64];

由于AllocatedMemory结构不实现Copy,因此无法工作

代码语言:javascript
复制
error: the trait `core::marker::Copy` is not implemented for the type `AllocatedMemory<'_, u8>` [E0277]
let array : [AllocatedMemory<u8>; 64] = [AllocatedMemory::<u8>{mem:&mut []}; 64];
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

所以我尝试了宏,但没有用:

代码语言:javascript
复制
struct AllocatedMemory<'a, T: 'a> {
    mem: &'a mut [T],
}

macro_rules! init_memory_helper {
    (1, $T : ty) => { AllocatedMemory::<$T>{mem: &mut []} };
    (2, $T : ty) => { init_memory_helper!(1, $T), init_memory_helper!(1, $T) };
    (4, $T : ty) => { init_memory_helper!(2, $T), init_memory_helper!(2, $T) };
    (8, $T : ty) => { init_memory_helper!(4, $T), init_memory_helper!(4, $T) };
    (16, $T : ty) => { init_memory_helper!(8, $T), init_memory_helper!(8, $T) };
    (32, $T : ty) => { init_memory_helper!(16, $T), init_memory_helper!(16, $T) };
    (64, $T : ty) => { init_memory_helper!(32, $T), init_memory_helper!(32, $T) };
}

macro_rules! init_memory {
    (1, $T : ty) => { [init_memory_helper!(1, $T)] };
    (2, $T : ty) => { [init_memory_helper!(2, $T)] };
    (4, $T : ty) => { [init_memory_helper!(4, $T)] };
    (8, $T : ty) => { [init_memory_helper!(8, $T)] };
    (16, $T : ty) => { [init_memory_helper!(16, $T)] };
    (32, $T : ty) => { [init_memory_helper!(32, $T)] };
    (64, $T : ty) => { [init_memory_helper!(64, $T)] };
}

fn main() {
    let array: [AllocatedMemory<u8>; 64] = init_memory!(64, u8);
    println!("{:?}", array[0].mem.len());
}

错误消息是

代码语言:javascript
复制
error: macro expansion ignores token `,` and any following
    (64, $T : ty) => { init_memory_helper!(32, $T), init_memory_helper!(32, $T) };
note: caused by the macro expansion here; the usage of `init_memory_helper!` is likely invalid in expression context

有没有办法在不剪切和粘贴每个初始化器的情况下初始化这个数组?

EN

回答 1

Stack Overflow用户

发布于 2020-01-08 00:13:11

Reddit启发运行在稳定平台上的"safe" implementation

代码语言:javascript
复制
// #![feature(core_intrinsics)]
// use std::ptr;
use std::mem;
use std::mem::MaybeUninit;

type MyStructValue = Vec<usize>;
type UsizeToVecBuilder = Box<dyn Fn(usize) -> Vec<usize>>;

#[derive(Debug)]
struct MyStruct {
    value: MyStructValue,
}

macro_rules! make_array {
    ([$t:ident; $n:expr], $constructor:expr, $builder:expr) => {{
        let mut data: [MaybeUninit<$t>; $n] = unsafe { MaybeUninit::uninit().assume_init() };

        let mut i: usize = 0;
        for elem in &mut data[..] {
            *elem = MaybeUninit::new($constructor(i, $builder));
            i += 1;
        }

        unsafe { mem::transmute::<_, [$t; $n]>(data) }
    }};
}

fn main() {
    println!(
        "{:?}",
        make_array!(
            [MyStruct; 5],
            |i, b: UsizeToVecBuilder| MyStruct { value: b(i) },
            Box::new(|i| (0..i + 1).collect())
        )
    );
}

// unstable version: (see reddit: https://www.reddit.com/r/rust/comments/29ymbx/a_macro_to_fill_a_fixed_length_array/)
//
// macro_rules! make_array {
//     ($n:expr, $constructor:expr) => {{
//         let mut items: [_; $n] = unsafe { mem::uninitialized() };
//         for i in 0..$n {
//             let val = $constructor(i);
//             unsafe {
//                 std::intrinsics::volatile_copy_nonoverlapping_memory(
//                     &mut items[i], &val, 1
//                 );
//                 // ptr::copy_nonoverlapping_memory(&mut items[i], &val, 1);
//                 mem::forget(val);
//             }
//         }
//         items
//     }}
// }

// fn main() {
// unstable version:
// println!("{:?}", make_array!(5, |i| MyStruct { value: i }));
// }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36258417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档