Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

cannot borrow `…` as mutable more than once at a time

Есть такой код:
fn count_sort<'a, D, T: 'a>(data: &'a mut D, min: T, max: T) where &'a mut D: IntoIterator, T: Sort + Clone + AddAssign, usize: From { let mut count = vec![0usize; usize::from(max) - usize::from(min) + 1usize];
for e in data.into_iter() { count[usize::from(e.clone())] += 1usize; }
let mut i = T::ZERO; let mut iter = data.into_iter(); for e in count.iter() { for _ in 0usize..*e { *iter.next().unwrap() = i.clone(); }
i += T::ONE; } }
И выдает он такую ошибку:
error[E0499]: cannot borrow*dataas mutable more than once at a time --> src\main.rs:21:20 | 16 | for e in data.into_iter() { | ---- first mutable borrow occurs here ... 21 | let mut iter = data.into_iter(); | ^^^^ second mutable borrow occurs here ... 29 | } | - first borrow ends here
Я понимаю в чем заключается ошибка, у ссылок на 16 и 21 строчках одинаковый lifetime, ведь я это указал в блоке where, но не понимаю, как это исправить, чтобы все работало. Помогите, пожалуйста.
Полный код, если надо:
use std::ops::AddAssign;

trait Sort { const ZERO: Self; const ONE: Self; }
fn count_sort<'a, D, T: 'a>(data: &'a mut D, min: T, max: T) where &'a mut D: IntoIterator, T: Sort + Clone + AddAssign, usize: From { let mut count = vec![0usize; usize::from(max) - usize::from(min) + 1usize];
for e in data.into_iter() { count[usize::from(e.clone())] += 1usize; }
let mut i = T::ZERO; let mut iter = data.into_iter(); for e in count.iter() { for _ in 0usize..*e { *iter.next().unwrap() = i.clone(); }
i += T::ONE; } }
impl Sort for u8 { const ZERO: u8 = 0; const ONE: u8 = 1; }
fn main() { let mut data = [3u8, 0, 2, 1];
println!("data = {:?}", data); count_sort(&mut data, 0, 3); println!("data = {:?}", data); }


Ответ

В данном случае нужно использовать Higher-Rank Trait Bounds:
fn count_sort(data: &mut D, min: T, max: T) where for <'x> &'x mut D: IntoIterator, T: Sort + Clone + AddAssign, usize: From
Вот еще отличный ответ на английском, где объясняется что это за магия.
P.S. У вас еще перепутаны местами min и max при создании вектора, rust выкидывает ошибку переполнения.

Комментариев нет:

Отправить комментарий