Допустим, у меня есть struct
, у которого есть коллекция, например Vec
в качестве одного из элементов данных:
struct MyCollection {
data: Vec<i32>
}
Я хочу, чтобы пользователь MyCollection
мог перебирать свои данные без прямого доступа к самой Vec
, например так:
let x = MyCollection{data:vec![1, 2, 3, 4, 5]};
for i in &x {
//...
}
Однако я пытаюсь реализовать необходимую черту IntoIterator
для не потребляющей версии с &x
, Я успешно реализовал потребляющую версию:
impl std::iter::IntoIterator for MyCollection {
type Item = i32;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
return self.data.into_iter();
}
}
Однако это можно использовать только следующим образом:
for i in x {
println!("{:?}", i);
}
, которая потребляет x
. Клонирование данных возможно, но довольно дорого, поэтому я бы хотел этого избежать.
Вот то, что я имею до сих пор для не потребляющей версии, которую я основал на реализации source из std::vec::Vec
:
impl<'a> std::iter::IntoIterator for &'a MyCollection {
type Item = &'a i32;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
return self.data.into_iter();
}
}
, что приводит к следующей ошибке компиляции:
error: mismatched types
error: expected &i32, found i32
note: expected type `std::vec::IntoIter<&i32>`
found type `std::vec::IntoIter<i32>`
error: expected `std::vec::IntoIter<&i32>` because of return type
Я также пытался удалить &'a
из type Item
, так как в моем случае элементы data
могут Copy
, но это дает следующее:
error: cannot move out of `self.data` which is behind a shared reference
error: move occurs because `self.data` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
Я понимаю, что функция хочет IntoIter
вектора для ссылок, но я не уверен, как дайте это эффективно. Я новичок в Rust, поэтому я был бы очень признателен за ясность по поводу проблемы. Бонусные баллы, если вы также можете сказать мне, как создать изменяемый итератор для доступа на запись таким же образом.