Инициализация вектора векторов в Rust - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь создать простой многоцветный генератор Мандельброта, расширяя пример, приведенный в «1001 * Programming Rust» О'Рейли . Идея состоит в том, чтобы создать три разных "плоскости" карты серого с немного отличающимися скоростями побега, а затем объединить их в цветное изображение в стиле RGB. Основная идея заключается в том, что каждая плоскость является независимой, поэтому каждая из них может обрабатываться отдельным потоком с использованием ящика crossbeam, который является конечной целью.

Проблема в том, что я не могу векторизовать свои самолеты. Позвольте мне показать вам:

pub struct Plane {
    bounds: (usize, usize),
    velocity: u8,
    region: Vec<u16>,
}

impl Plane {
    pub fn new(width: usize, height: usize, velocity: u8) -> Plane {
        Plane {
            bounds: (width, height),
            velocity: velocity,
            region: vec![0 as u16; width * height],
        }
    }
}

pub fn main() {
    // ... argument processing elided
    let width = 1000;
    let height = 1000;
    let velocity = 10;
    let planes = vec![Plane::new(width, height, velocity); 4]; // RGBa
}

Когда я пытаюсь построить это, я получаю:

error[E0277]: the trait bound `Plane: std::clone::Clone` is not satisfied
  --> src/main.rs:23:18
   |
23 |     let planes = vec![Plane::new(width, height, velocity); 4]; // RGBa
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Plane`
   |
   = note: required by `std::vec::from_elem`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

Я попытался создать одну гигантскую плоскость и затем разрезать ее на подпланы с помощью chunks_mut, а затем передать ссылки на лежащие в основе массивы, но тогда это дает мне:

region: &' [u16]: this field does not implement 'Copy'

Насколько я могу судить, я не пытаюсь скопировать объект Plane, но макрос vec![] хочет переместить куда-то, для чего должен быть реализован Copy, но внутри этого я просто хочу переместить дескриптор массива, а не данные, верно? И это только само растровое изображение, разве не должно быть уже реализовано Copy?

Это прекрасно работает на одной плоскости, даже когда эта плоскость разрезана на области для многоядерной обработки (см. Пример здесь ), хотя в этом случае «один гигантский» plane "живет в родительской функции, и только его части передаются средству визуализации.

Есть ли способ переместить массив плоских данных в структуру для правильной инкапсуляции?

1 Ответ

0 голосов
/ 29 августа 2018

Строительный макрос Vec vec![val; n] требует, чтобы тип элемента реализовал Clone, чтобы он мог скопировать элемент примера в оставшиеся слоты. Таким образом, простое решение заключается в том, чтобы Plane реализовать Clone:

#[derive(Clone)]
pub struct Plane {
    bounds: (usize, usize),
    velocity: u8,
    region: Vec<u16>,
}

Кроме того, вы можете просто заполнить вектор другим способом, который не зависит от элементов, реализующих Clone. Например:

use std::iter;
let planes: Vec<_> = iter::repeat_with(|| Plane::new(width, height, velocity))
    .take(4)
    .collect();
...