【问题标题】:What is the difference between `Some(&a) => a` and `Some(a) => *a` when matching an Option?匹配选项时,`Some(&a) => a` 和 `Some(a) => *a` 有什么区别?
【发布时间】:2018-06-26 13:51:30
【问题描述】:

为什么会通过:

fn f(v: Vec<isize>) -> (Vec<isize>, isize) {
    match v.get(0) {
        Some(&a) => (v, a),
        _ => (v, 0)
    }
}

Playground

但这不是?:

fn f(v: Vec<isize>) -> (Vec<isize>, isize) {
    match v.get(0) {
        Some(a) => (v, *a),
        _ => (v, 0)
    }
}

Playground

error[E0505]: cannot move out of `v` because it is borrowed
 --> src/main.rs:7:21
  |
6 |     match v.get(0) {
  |           - borrow of `v` occurs here
7 |         Some(a) => (v, *a),
  |                     ^ move out of `v` occurs here

【问题讨论】:

    标签: rust borrowing


    【解决方案1】:

    v.get(0) 返回对向量中元素的引用,因此您匹配的是&amp;isizeVec 现在借用在匹配臂中。

    在第一个代码 sn-p 中,您复制了 isize,因此这里没有借用 Vec。在第二个 sn-p 中,Vec 仍然是借用的,因此您不能将其移出范围。

    但是,您应该考虑使用if letunwrap_or

    fn f(v: Vec<isize>) -> (Vec<isize>, isize) {
        let a = v.get(0).cloned();
        (v, a.unwrap_or(0))
    }
    

    Playground

    fn f(v: Vec<isize>) -> (Vec<isize>, isize) {
        if let Some(&a) = v.get(0) {
            (v, a)
        } else {
            (v, 0)
        }
    }
    

    Playground


    另见:

    【讨论】:

      【解决方案2】:

      在第一个 sn-p 中,当你键入 Some(&amp;a) 时,你不要借用 v,因为 a 被复制了。

      在第二种情况下,Some(a) 的类型为 Option&lt;&amp;isize&gt;,因此它包含对 v 的引用。当您尝试移动它时,它会触发错误。如果你先复制它,然后返回这对,它就可以工作(但是你需要NLL feature):

      #![feature(nll)]
      
      fn main() {
          println!("{:?}", f(vec![1]))
      }
      
      fn f(v: Vec<isize>) -> (Vec<isize>, isize) {
          match v.get(0) {
              Some(a) => {
                  let a = *a; // v is no more borrowed
                  (v, a)
              },
              _ => (v, 0)
          }
      }
      

      Playground

      借用检查器不可能完美,所以你经常会遇到一些稍微不一致的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-27
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        • 2013-06-25
        • 2020-10-09
        相关资源
        最近更新 更多