Using a macro to initialize a big array of non-Copy elements

前端 未结 3 1368
北海茫月
北海茫月 2021-01-19 21:57

I\'m trying to initialize a big array of elements with the same initializer. 64 elements is just an example — I want to make it at least 16k. Unfortunately a simple

3条回答
  •  鱼传尺愫
    2021-01-19 22:44

    A "safe" implementation which runs on stable, heavily inspired by Reddit:

    // #![feature(core_intrinsics)]
    // use std::ptr;
    use std::mem;
    use std::mem::MaybeUninit;
    
    type MyStructValue = Vec;
    type UsizeToVecBuilder = Box Vec>;
    
    #[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 }));
    // }
    

提交回复
热议问题