rust - 展开时无法移出共享引用后面的值

标签 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 )

我在以前的 Rust 版本中遇到以下错误:

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

在更现代的版本中:

error[E0507]: cannot move out of `*arg1` which is behind a shared reference
 --> src/main.rs:5:19
  |
5 |     let integer = arg1.unwrap();
  |                   ^^^^
  |                   |
  |                   move occurs because `*arg1` has type `std::option::Option<std::boxed::Box<i32>>`, which does not implement the `Copy` trait
  |                   help: consider borrowing the `Option`'s content: `arg1.as_ref()`

我看到已经有很多关于borrow checker问题的文档,但是看了之后,我还是没弄清楚问题所在。

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

最佳答案

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 组合器,例如 Option::as_refOption::as_mutOption::map_or 配对,正如 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 提升为静态值以保留,以便在缺少输入值的情况下能够返回它。

关于rust - 展开时无法移出共享引用后面的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32338659/

相关文章:

rust - 我在这段代码中为队列实现 `dequeue` 函数做错了什么?

rust - 为什么不能在同一结构中存储值和对该值的引用?

rust - 使用包含借用参数的结构

rust - 将包含引用的结构移动到静态闭包中不起作用

function - Rust 函数如何修改数组索引的值?

rust - 如何使用 serde 序列化选项?

rust - 如何解决传递给闭包的 &PathBuf 冲突的生命周期要求?

rust - 外部库作为对本地库的依赖

numpy - ndpointer将Numpy Array转换为Rust,在Windows中失败(在Linux上运行)

rust - 如何解决此类项目中的借用和可变性 hell ?