Я думаю, что проблема вызвана временным кортежем в первом l oop. Создание кортежа перемещает его компоненты в новый кортеж, и это происходит, даже если последующее сопоставление с образцом не удается.
Во-первых, позвольте мне написать более простую версию вашего кода. Это прекрасно компилируется:
struct Foo(i32);
fn main() {
let mut longer = Foo(0);
while let Foo(x) = longer {
longer = Foo(x + 1);
}
println!("{:?}", longer.0);
}
Но если я добавлю временное к while let
, я вызову ошибку компилятора, похожую на вашу:
fn fwd<T>(t: T) -> T { t }
struct Foo(i32);
fn main() {
let mut longer = Foo(0);
while let Foo(x) = fwd(longer) {
longer = Foo(x + 1);
}
println!("{:?}", longer.0);
// Error: ^ borrow of moved value: `longer`
}
Решение состоит в том, чтобы добавить локальная переменная со значением, подлежащим деструктуризации, вместо использования временной. В вашем коде:
struct List {
next: Option<Box<List>>
}
fn drain_lists(shorter: Option<Box<List>>,
longer: Option<Box<List>>) {
// Pair the elements in the two lists.
let mut twolists = (shorter, longer);
while let (Some(node1), Some(node2)) = twolists {
// Actual work elided.
twolists = (node1.next, node2.next);
}
// Process the rest in the longer list.
let (_, mut longer) = twolists;
while let Some(node) = longer {
// Actual work elided.
longer = node.next;
}
}