Изменяемо перебирать итератор, используя tuple_windows Itertools

Я пытаюсь сохранить серию записей внутри Vec. Позже мне нужно повторно обработать через Vec, чтобы заполнить некоторую информацию в каждой записи о следующей записи. Минимальный пример будет примерно таким:

struct Entry {
    curr: i32,
    next: Option<i32>
}

struct History {
    entries: Vec<Entry>
}

где я хотел бы заполнить поля next значением curr следующих записей. Для этого я хочу использовать функцию tuple_windows из Itertools для изменяемого итератора. Я ожидаю, что смогу написать такую ​​функцию:

impl History {    
    fn fill_next_with_itertools(&mut self) {
        for (a, b) in self.entries.iter_mut().tuple_windows() {
            a.next = Some(b.curr);
        }
    }
}

(детская площадка)

Однако он отказывается компилироваться, потому что тип итератора Item, &mut Entry, не является Clone, который требуется для функции tuple_windows. Я понимаю, что есть способ перебрать список, используя такие индексы:

    fn fill_next_with_index(&mut self) {
        for i in 0..(self.entries.len()-1) {
            self.entries[i].next = Some(self.entries[i+1].curr);
        }
    }

(детская площадка)

Но я считаю подход itertools более естественным и элегантным. Каковы наилучшие способы достижения того же эффекта?

Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
0
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из документации :
tuple_window клонирует элементы итератора, чтобы они могли быть частью последовательных окон, что делает его наиболее подходящим для итераторов ссылок и других значений, которые дешево копировать.

Это означает, что если бы вы реализовали его с элементами &mut, то у вас было бы несколько изменяемых ссылок на одно и то же, поведение которого не определено.

Если вам все еще нужен общий, изменяемый доступ, вам придется обернуть его в Rc<RefCell<T>>, Arc<Mutex<T>> или что-то подобное:

fn fill_next_with_itertools(&mut self) {
    for (a, b) in self.entries.iter_mut().map(RefCell::new).map(Rc::new).tuple_windows() {
        a.borrow_mut().next = Some(b.borrow().curr);
    }
}

Другие вопросы по теме