4

为什么会通过:

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

操场

但这不是?:

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

操场

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
4

2 回答 2

1

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

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

但是,您应该考虑使用if letor unwrap_or

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

操场

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

操场


也可以看看:

于 2018-06-26T14:15:52.533 回答
0

在第一个片段中,当您键入 时Some(&a),您不会借用v,因为a它被复制了。

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

#![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)
    }
}

操场

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

于 2018-06-26T14:09:14.190 回答