生锈 – 匹配期权时,有些(&a)=> a`和`Some(a)=> * a`有什么区别?

为什么这会通过:

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

最佳答案
v.get(0)返回对向量中元素的引用,因此您匹配& isize. Vec现在在比赛中借用.

在第一个代码段中,您复制了isize,因此不会在此处借用Vec.在第二个片段中,Vec仍然被借用,因此您无法将其移出范围.

但是,您应该考虑使用let或unwrap_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

也可以看看:

> How do I not borrow an Option when matching?
> How do I borrow a reference to what is inside an Option<T>?
> Cannot move out of borrowed content

点赞