为什么通过:
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
答案 0 :(得分:1)
v.get(0)
返回对向量中元素的引用,因此您正在匹配&isize
。 Vec
现在在匹配臂中借用了。
在第一个代码段中,您复制了isize
,因此这里没有借用Vec
。在第二个片段中,Vec
仍然是借用的,因此您不能将其移出范围。
但是,您应该考虑使用if let
或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)
}
}
另请参阅:
答案 1 :(得分:0)
在第一个代码段中,键入Some(&a)
时,您不会借用v
,因为复制了a
。
在第二种情况下,Some(a)
的类型为Option<&isize>
,因此它包含对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)
}
}
借阅检查器并不完美,因此您经常会遇到一些稍微不一致的内容。