匹配Option时`Some(&a) => a`和`Some(a) => *a`有什么区别?
What is the difference between `Some(&a) => a` and `Some(a) => *a` when matching an Option?
为什么会通过:
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
在第一个片段中,当您键入 Some(&a)
时,您没有借用 v
,因为 a
被复制了。
在第二种情况下,Some(a)
是 Option<&isize>
类型,因此它持有对 v
的引用。当您尝试移动它时,它会触发错误。如果你先复制它,然后你 return 这对,它会起作用(但是你需要 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)
}
}
借用检查器不可能是完美的,因此您经常会遇到一些稍微不一致的东西。
v.get(0)
returns 对向量中元素的引用,因此您正在匹配 &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)
}
}
另请参阅:
- How do I not borrow an Option when matching?
- How do I borrow a reference to what is inside an Option<T>?
为什么会通过:
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
在第一个片段中,当您键入 Some(&a)
时,您没有借用 v
,因为 a
被复制了。
在第二种情况下,Some(a)
是 Option<&isize>
类型,因此它持有对 v
的引用。当您尝试移动它时,它会触发错误。如果你先复制它,然后你 return 这对,它会起作用(但是你需要 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)
}
}
借用检查器不可能是完美的,因此您经常会遇到一些稍微不一致的东西。
v.get(0)
returns 对向量中元素的引用,因此您正在匹配 &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)
}
}
另请参阅:
- How do I not borrow an Option when matching?
- How do I borrow a reference to what is inside an Option<T>?