Я знаю, что Rust не поддерживает массивы переменной длины, но это заставляет меня задуматься, чем их заменить, учитывая, что:
- Я не хочу выделять и освобождать крошечный Vec в цикле
- Средство проверки заимствований не позволяет мне вывести код за пределы цикла
- Есть много ограничений на массивы фиксированного размера, поэтому я не могу понять, как их использовать.
Код C, который я конвертирую, обрабатывает изображение, вызывая обратный вызов в каждой строке, передавая небольшой массив указателей:
float *tmp[img->channels]; // Small, up to 4 elements
for(int y = 0; y < height; y++) {
for(int ch = 0; ch < img->channels; ch++) {
tmp[ch] = &img->channel[ch]->pixels[width * y];
}
callback(tmp, img->channels);
}
Моя попытка Rust (пример в playpen):
for y in 0..height {
let tmp = &img.channel.iter().map(|channel| {
&mut channel.pixels.as_ref().unwrap()[width * y .. width * (y+1)]
}).collect();
callback(tmp);
}
Но это отклонено:
коллекция типа
[&mut [f32]]
не может быть построена из итератора по элементам типа&mut [f32]
К сожалению, это похоже на то, что я пытался сделать!
Я пробовал использовать массив фиксированного размера, но Rust не поддерживает для них дженерики, поэтому я не могу заполнить его с помощью итератора, и я не могу заполнить их в цикле, подобном C, потому что ссылки, взятые в петля не переживает этого.
признак
core::iter::FromIterator<&mut [f32]>
не реализован для типа[&mut [f32]; 4]
Другой подход с извлечением фрагмента памяти из массива фиксированного размера также не работает:
let mut row_tmp: [&mut [f32]; 4] = unsafe{mem::zeroed()};
for y in 0..height {
row_tmp[0..channels].iter_mut().zip(img.chan.iter_mut()).map(|(t, chan)| {
*t = &mut chan.img.as_ref().unwrap()[(width * y) as usize .. (width * (y+1)) as usize]
});
cb(&row_tmp[0..channels], y, width, image_data);
}
ошибка: нельзя заимствовать
img.chan
как изменяемый более одного раза за раз