У меня возникли трудности с получением контролера заимствования, работающего на простой итеративный построитель связанных списков.Создание простого связанного списка
fn main() {
let v = vec![1,5,3,8,12,56,1230,2,1];
let nodes = Vec::<Node>::with_capacity(v.len());
let mut root: Option<&mut Box<Node>> = None;
let mut prev: &Option<&mut Box<Node>> = &None;
for i in v {
let curr = Some(&mut Box::new(Node { value: i, next: None }));
match *prev {
Some(ref mut p) => {
p.next = curr;
prev = &mut p.next;
},
None => {
root = curr;
prev = &mut root;
}
}
}
}
struct Node<'a> {
value: i32,
next: Option<&'a mut Box<Node<'a>>>,
}
Ошибки я получаю, когда я пытаюсь скомпилировать:
linked_list.rs:8:30: 8:69 error: borrowed value does not live long enough
linked_list.rs:8 let curr = Some(&mut Box::new(Node { value: i, next: None }));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of for loop expansion
linked_list.rs:7:5: 19:6 note: expansion site
linked_list.rs:4:49: 20:2 note: reference must be valid for the block suffix following statement 2 at 4:48...
linked_list.rs:4 let mut root: Option<&mut Box<Node>> = None;
linked_list.rs:5 let mut prev: &Option<&mut Box<Node>> = &None;
linked_list.rs:6
linked_list.rs:7 for i in v {
linked_list.rs:8 let curr = Some(&mut Box::new(Node { value: i, next: None }));
linked_list.rs:9 match *prev {
...
linked_list.rs:8:9: 8:71 note: ...but borrowed value is only valid for the statement at 8:8
linked_list.rs:8 let curr = Some(&mut Box::new(Node { value: i, next: None }));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
linked_list.rs:8:9: 8:71 help: consider using a `let` binding to increase its lifetime
linked_list.rs:8 let curr = Some(&mut Box::new(Node { value: i, next: None }));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
linked_list.rs:10:18: 10:27 error: cannot borrow immutable anonymous field `(prev:core::option::Some).0` as mutable
linked_list.rs:10 Some(ref mut p) => {
^~~~~~~~~
note: in expansion of for loop expansion
linked_list.rs:7:5: 19:6 note: expansion site
linked_list.rs:15:17: 15:28 error: cannot assign to `root` because it is borrowed
linked_list.rs:15 root = curr;
^~~~~~~~~~~
note: in expansion of for loop expansion
linked_list.rs:7:5: 19:6 note: expansion site
linked_list.rs:16:29: 16:33 note: borrow of `root` occurs here
linked_list.rs:16 prev = &mut root;
^~~~
note: in expansion of for loop expansion
linked_list.rs:7:5: 19:6 note: expansion site
linked_list.rs:16:29: 16:33 error: cannot borrow `root` as mutable more than once at a time
linked_list.rs:16 prev = &mut root;
^~~~
note: in expansion of for loop expansion
linked_list.rs:7:5: 19:6 note: expansion site
linked_list.rs:16:29: 16:33 note: previous borrow of `root` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `root` until the borrow ends
linked_list.rs:16 prev = &mut root;
^~~~
note: in expansion of for loop expansion
linked_list.rs:7:5: 19:6 note: expansion site
linked_list.rs:20:2: 20:2 note: previous borrow ends here
linked_list.rs:1 fn main() {
...
linked_list.rs:20 }
^
error: aborting due to 4 previous errors
То, что я пытаюсь идти довольно просто. Мы перебираем Vec, создавая новый узел на каждой итерации. Если prev является None, это должно быть началом, поэтому мы делаем корневую переменную собственностью этого первого узла. Если это не так, мы обновим следующее значение предыдущего узла, чтобы указать на этот узел.
Я новичок в Rust, поэтому не уверен, где я ошибаюсь. Моя интерпретация заключается в том, что средство проверки займов не справляется с этим. Он не может сделать вывод о том, что ветвь «Нет» в матче, содержащая «корневое» назначение, будет когда-либо вызываться только один раз, в результате чего две ошибки о заимствовании корня дважды. Я прав?
Возможно ли такое использование в ржавчине? Есть ли более идиоматический способ сделать такие вещи?
(Рекурсивный подход, вероятно, гораздо проще, но я хотел бы завершить повторяющийся в качестве учебного упражнения.)
Почему этот вопрос не должен быть помечен как дубликат [этого] (http://stackoverflow.com/q/21152429/155423), [этот] (http://stackoverflow.com/q/30441456/155423), [этот] (http://stackoverflow.com/q/22268861/155423), [этот] (http://stackoverflow.com/q/27750985/155423) или [этот] (http://stackoverflow.com/q/26434364/155423)? – Shepmaster