问题
This is the code I am trying to execute:
fn my_fn(arg1: &Option<Box<i32>>) -> (i32) {
if arg1.is_none() {
return 0;
}
let integer = arg1.unwrap();
*integer
}
fn main() {
let integer = 42;
my_fn(&Some(Box::new(integer)));
}
(on the Rust playground)
I get the following error:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:5:19
|
5 | let integer = arg1.unwrap();
| ^^^^ cannot move out of borrowed content
I see there is already a lot of documentation about borrow checker issues, but after reading it, I still can't figure out the problem.
Why is this an error and how do I solve it?
回答1:
Option::unwrap() consumes the option, that is, it accepts the option by value. However, you don't have a value, you only have a reference to it. That's what the error is about.
Your code should idiomatically be written like this:
fn my_fn(arg1: &Option<Box<i32>>) -> i32 {
match arg1 {
Some(b) => **b,
None => 0,
}
}
fn main() {
let integer = 42;
my_fn(&Some(Box::new(integer)));
}
(on the Rust playground)
Or you can use Option
combinators like Option::as_ref or Option::as_mut paired with Option::map_or, as Shepmaster has suggested:
fn my_fn(arg1: &Option<Box<i32>>) -> i32 {
arg1.as_ref().map_or(0, |n| **n)
}
This code uses the fact that i32
is automatically copyable. If the type inside the Box
weren't Copy
, then you wouldn't be able to obtain the inner value by value at all - you would only be able to clone it or to return a reference, for example, like here:
fn my_fn2(arg1: &Option<Box<i32>>) -> &i32 {
arg1.as_ref().map_or(&0, |n| n)
}
Since you only have an immutable reference to the option, you can only return an immutable reference to its contents. Rust is smart enough to promote the literal 0
into a static value to keep in order to be able to return it in case of absence of the input value.
来源:https://stackoverflow.com/questions/32338659/cannot-move-out-of-borrowed-content-when-unwrapping