Я создаю пользовательскую структуру данных в Rust и пытаюсь реализовать для нее итераторы. Следуя примеру встроенных коллекций (LinkedList
, Vec
и т. Д.), Я создал структуру IntoIter
, которая выполняет итерацию по принадлежащей коллекции, структуру Iter
, которая выполняет итерацию по заимствованной коллекции, и структуру IterMut
, которая выполняет итерацию по изменяемой коллекции. заимствованная коллекция.
Мне удалось реализовать первые два итератора, но у меня возникли проблемы с обслуживанием средства проверки заимствований с помощью IterMut
. Я сократил свой код до минимума воспроизведения и заменил свою собственную структуру данных на Vec<Option<T>>
:
pub struct IterMut<'a, T: 'a> {
list: &'a mut Vec<Option<T>>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<&'a mut T> {
let head_node = &mut self.list[0];
// convert &mut Option<T> to Option<&mut T>
head_node.as_mut()
}
}
Не удается скомпилировать с
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:23:24
|
23 | let head_node = &mut self.list[0];
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 22:2...
--> src/main.rs:22:2
|
22 | / fn next(&mut self) -> Option<&'a mut T> {
23 | | let head_node = &mut self.list[0];
24 | | // convert &mut Option<T> to Option<&mut T>
25 | | head_node.as_mut()
26 | | }
| |__^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:23:24
|
23 | let head_node = &mut self.list[0];
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 19:1...
--> src/main.rs:19:1
|
19 | / impl<'a, T> Iterator for IterMut<'a, T> {
20 | | type Item = &'a mut T;
21 | |
22 | | fn next(&mut self) -> Option<&'a mut T> {
... |
26 | | }
27 | | }
| |_^
note: ...so that expression is assignable (expected std::option::Option<&'a mut T>, found std::option::Option<&mut T>)
--> src/main.rs:25:3
|
25 | head_node.as_mut()
| ^^^^^^^^^^^^^^^^^^
Что меня действительно смущает, так это то, что этот код почти идентичен коду, который я использовал для Iter
, который успешно компилируется:
pub struct Iter<'a, T: 'a> {
list: &'a Vec<Option<T>>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
let head_node = &self.list[0];
// convert &Option<T> to Option<&T>
head_node.as_ref()
}
}
Я знаю, что &
и &mut
- две разные вещи, но я думал, что их время жизни будет рассчитываться одинаково. Мое первое предположение заключалось в том, что as_ref()
должно чем-то отличаться от as_mut()
, но, похоже, нет разницы в исходном коде их реализаций (as_ref, as_mut).
На что жалуется контролер заемщиков?
&mut self.list[0]
), вы нарушите правила Rust для ссылок! Вот повторяющийся ответ, примененный к вашему коду. - person Shepmaster   schedule 18.12.2017