fn populate(next: &mut Option<Box<Node>>) -> Option<Node> {
let node = Node { value: true, next: None };
let result = Some(Box::new(node));
*next = result;
Some(*result.unwrap() /* *next.unwrap() */)
}
Массаж кода, как предлагает компилятор, может привести к тому, что вы написали. Теперь, принимая его, введение промежуточных переменных и аннотирующих типов (чтобы увидеть, что происходит) дает следующее:
fn populate2(next: &mut Option<Box<Node>>) -> Option<Node> {
let node : Node = Node { value: true, next: None };
let result : Option<Box<Node>> = Some(Box::new(node));
*next = result;
let next_as_ref : Option<&Box<Node>> = next.as_ref();
let next_as_ref_unwrap : &Box<Node> = next_as_ref.unwrap();
let next_as_ref_unwrap_deref : Box<Node> = *next_as_ref_unwrap; // <- error here!
Some(*next_as_ref_unwrap_deref) // or Some(*next.unwrap())
}
let next_as_ref_unwrap_deref : Box<Node> = *next_as_ref_unwrap;
терпит неудачу, потому что next_as_ref_unwrap
является заимствованным Box<Node>
, то есть &Box<Node>
. Разыменование (т. Е. *
) next_as_ref_unwrap
пытается переместиться, чего нельзя сделать из заимствованной переменной.
Проблема в том, что у вас есть next
, который содержит (по существу) Node
, однако Вы хотите вернуть a Node
. Возникает вопрос: хотите ли вы вернуть другой (то есть new Node
) или вы хотите извлечь (то есть take
) Node
из next
и вернуть его. В случае, если вы хотите take
и вернуть его:
fn populate(next: &mut Option<Box<Node>>) -> Option<Node> {
let node = Node { value: true, next: None };
let result = Some(Box::new(node));
*next = result;
next.take().map(|boxed_node| *boxed_node)
}
Приведенный выше код компилируется, но, по крайней мере, сомнительно, так как он принимает next
, который по существу используется в качестве локальной переменной и сделал None
впоследствии (потому что мы take
из него).
Вы, вероятно, хотите решить, что на самом деле должен делать populate
.
- Должно ли оно изменить
None
? Почему возвращаемое значение Option<None>
? Должно ли оно вернуть старое значение next
? (Зачем возвращать Option<Node>
вместо Option<Box<Node>>
тогда?)
Код:
fn populate_returning_old_val(next: &mut Option<Box<Node>>) -> Option<Node> {
std::mem::replace(
next,
Some(Box::new(Node { value: true, next: None }))
).take().map(|boxed_node| *boxed_node)
}