arraysrustsyntaxconcatenationliterals

Can you concatenate array literals at compile time in rust?


is there any way to concat array literals in rust?

For example, I want an array like [0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9]

I can define an array [0; 8] and a [6, 9], but is there any way to write this into one definition? The only way I know is writing the whole thing out like

let array: [u8; 10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9];

But is there any way then to wrap the zeros? If I for example want 500 instead of 8 zeros?

I only know it's possible to concat the arrays in runtime, and that's also very complicated, but is there like a literal syntax where you can combine to slices?

Thank you


Solution

  • There is no syntax for that, but that is possible, and a macro can make this nicer:

    macro_rules! concat_arrays {
        ( $ty:ty, $default:expr => $($arr:expr),* $(,)? ) => {{
            const __CONCAT_ARRAYS__LEN: usize = 0 $( + $arr.len() )*;
            const __CONCAT_ARRAYS__RESULT: [$ty; __CONCAT_ARRAYS__LEN] = {
                let mut result = [$default; __CONCAT_ARRAYS__LEN];
                let mut result_idx = 0;
                $(
                    let arr = $arr;
                    let mut src_idx = 0;
                    while src_idx < arr.len() {
                        result[result_idx] = arr[src_idx];
                        src_idx += 1;
                        result_idx += 1;
                    }
                )*
                result
            };
            __CONCAT_ARRAYS__RESULT
        }};
    }
    
    let array: [u8; 10] = concat_arrays!(u8, 0 => [0; 8], [6, 9]);
    

    $default is just some temporary value needed for the macro. It can be worked around with more powerful const eval or unsafe code.