代码之家  ›  专栏  ›  技术社区  ›  ZNackasha

当选项可用时,如何展开该选项,否则如何返回默认参考值?[副本]

  •  1
  • ZNackasha  · 技术社区  · 6 年前

    这是我试图执行的代码:

    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()`
    

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

    0 回复  |  直到 5 年前
        1
  •  20
  •   Shepmaster Tim Diekmann    6 年前

    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_ref Option::as_mut 配对 Option::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)
    }
    

    0 输入一个静态值,以便在没有输入值的情况下能够返回它。

        2
  •  1
  •   Daniel    3 年前

    因为锈1.40,所以 Option::as_deref ,现在您可以执行以下操作:

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