Каков правильный шаблон для вектора структур, где каждая структура содержит подмножество массива структур? - PullRequest
0 голосов
/ 31 марта 2020

У меня есть код, очень похожий на следующий (хотя моя функция фильтрации более сложная):

struct MyStruct {
    a: i32,
    b: i32,
    count: i32,
}

impl MyStruct {
    fn filter(&self) -> bool {
        return self.a > self.b + self.count;
    }
}
struct ContainerStruct<'a> {
    x: i32,
    v: Vec<&'a MyStruct>,
}

fn main() {
    let mut list_of_items = vec![
        MyStruct {
            a: 1,
            b: 2,
            count: 0,
        },
        MyStruct {
            a: 2,
            b: 1,
            count: 0,
        },
        MyStruct {
            a: 5,
            b: 2,
            count: 0,
        },
    ];
    let mut count = 0;
    let mut list_of_containers: Vec<ContainerStruct> = Vec::new();
    while count < 10 {
        let mut c = ContainerStruct {
            x: 1,
            v: Vec::new(),
        };

        for i in list_of_items.iter_mut() {
            i.count = count;
            if i.filter() {
                c.v.push(i);
            }
        }
        count += 1;
        list_of_containers.push(c)
    }
}

, который не компилируется из-за следующей ошибки:

error[E0499]: cannot borrow `list_of_items` as mutable more than once at a time
  --> src/main.rs:43:18
   |
43 |         for i in list_of_items.iter_mut() {
   |                  ^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop

Я знаю, что это проблема проверки заимствований, и я вижу потенциальные проблемы со ссылками и т. Д. c. Чего я не знаю, так это правильного шаблона, который нужно использовать для достижения того, что я ищу, - по сути, это вектор структур, где каждая структура содержит подмножество массива структур.

Мне нужно быть в состоянии изменить структуры, поэтому я вынужден использовать iter_mut().

Однако это перемещает вектор в ту область, которая затем высвобождается в следующий раз, когда я go через внешний, тогда как l oop .

Есть ли способ заставить вектор жить достаточно долго, чтобы завершить внешний l oop? Я думал о копировании структур, но я не хочу этого делать. Мне нужны только ссылки на каждый из них, и копирование может привести к неприемлемым издержкам из-за размера рассматриваемого вектора.

1 Ответ

0 голосов
/ 01 апреля 2020

Это компилируется:

use std::cell::Cell;

struct MyStruct {
    a: i32,
    b: i32,
    count: Cell<i32>,
}

impl MyStruct {
    fn filter(&self) -> bool {
        return self.a > self.b + self.count.get();
    }
}
struct ContainerStruct<'a> {
    x: i32,
    v: Vec<&'a MyStruct>,
}

fn main() {
    let mut list_of_items = vec![
        MyStruct {
            a: 1,
            b: 2,
            count: Cell::new(0),
        },
        MyStruct {
            a: 2,
            b: 1,
            count: Cell::new(0),
        },
        MyStruct {
            a: 5,
            b: 2,
            count: Cell::new(0),
        },
    ];
    let mut count = 0;
    let mut list_of_containers: Vec<ContainerStruct> = Vec::new();
    while count < 10 {
        let mut c = ContainerStruct {
            x: 1,
            v: Vec::new(),
        };

        for i in list_of_items.iter() {
            i.count.set(count);
            if i.filter() {
                c.v.push(i);
            }
        }
        count += 1;
        list_of_containers.push(c)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...