Есть ли способ объединить литералы массива в Rust?
Например, мне нужен массив типа [0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9]
Я могу определить массив [0; 8] и [6, 9], но есть ли способ записать это в одно определение? Единственный способ, который я знаю, - это записать все это как
let array: [u8; 10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9];
Но есть ли способ тогда обернуть нули? Если я например хочу 500 вместо 8 нулей?
Я знаю только, что массивы можно объединить во время выполнения, и это тоже очень сложно, но существует ли какой-то буквальный синтаксис, который можно объединить в срезы?
Спасибо



Для этого нет синтаксиса, но это возможно, и макрос может сделать это лучше:
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 — это просто временное значение, необходимое для макроса. Эту проблему можно обойти с помощью более мощного константного кода или небезопасного кода.
Хорошо, спасибо, я думаю, это не идеальное решение, поскольку оно объединяет массивы во время выполнения, а не объединяет литералы во время компиляции, но я думаю, с этим можно жить.
@blueSheesh: они объединяются в контексте const, который оценивается во время компиляции.
Другим возможным решением для значения по умолчанию может быть что-то вроде const-default.