展开时无法摆脱借来的内容

时间:2015-09-01 18:33:29

标签: rust borrow-checker

这是我试图执行的代码:

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

我收到以下错误:

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:5:19
  |
5 |     let integer = arg1.unwrap();
  |                   ^^^^ cannot move out of borrowed content

我看到已经有很多关于借阅检查器问题的文档,但在阅读之后,我仍然无法弄清楚问题。

为什么这是一个错误,我该如何解决?

2 个答案:

答案 0 :(得分:11)

Option::unwrap()使用该选项,即它按值接受该选项。但是,您没有价值,您只能参考它。这就是错误的含义。

您的代码应按惯例写成:

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

或者,您可以使用Option::as_refOption::as_mutOption::map_or配对的Option个组合,正如Shepmaster建议的那样:

fn my_fn(arg1: &Option<Box<i32>>) -> i32 {
    arg1.as_ref().map_or(0, |n| **n)
}

此代码使用i32可自动复制的事实。如果Box中的类型不是Copy,那么您根本无法按值获取内部值 - 您只能克隆它或者返回引用,例如,像这里:

fn my_fn2(arg1: &Option<Box<i32>>) -> &i32 {
    arg1.as_ref().map_or(&0, |n| n)
}

由于您只有对该选项的不可变引用,因此您只能返回对其内容的不可变引用。 Rust足够聪明,可以将文字0提升为静态值,以便在缺少输入值时能够返回它。

答案 1 :(得分:0)

从 Rust 1.40 开始就有 Option::as_deref,所以现在你可以这样做:

fn my_fn(arg1: &Option<Box<i32>>) -> i32 {
    *arg1.as_deref().unwrap_or(&0)
}