编译以下代码:
fn consume(_: Box<u64>) {}
let tuple = (Some(Box::new(1)), Some(Box::new(2)));
match tuple {
(Some(x), Some(y)) => {
consume(x);
consume(y);
}
_ => (),
}
编译以下代码:
fn consume(_: Box<u64>) {}
match [Some(Box::new(1)), Some(Box::new(2))] {
[Some(x), Some(y)] => {
consume(x);
consume(y);
}
_ => (),
}
但是这段代码无法编译:
fn consume(_: Box<u64>) {}
let array = [Some(Box::new(1)), Some(Box::new(2))];
match array {
[Some(x), Some(y)] => {
consume(x);
consume(y);
}
_ => (),
}
编译器说:
error[E0382]: use of moved value: `(array[..] as std::prelude::v1::Some).0`
--> src/main.rs:5:24
|
5 | [Some(x), Some(y)] => {
| - ^ value used here after move
| |
| value moved here
|
= note: move occurs because the value has type `std::boxed::Box<u64>`, which does not implement the `Copy` trait
为什么第一版和第二版可以通过,第三版不行?
最佳答案
这是您的代码的简化版本:
struct NonCopy;
fn main() {
// OK
let tuple = (Some(NonCopy), Some(NonCopy));
if let (Some(_x), Some(_y)) = tuple {}
// OK
if let [Some(_x), Some(_y)] = [Some(NonCopy), Some(NonCopy)] {}
// Fails
let array = [Some(NonCopy), Some(NonCopy)];
if let [Some(_x), Some(_y)] = array {}
}
好消息
此代码在 non-lexical lifetimes are enabled 时按原样工作.
坏消息
非词汇生命周期还不稳定。
解决方法
将数组的所有权显式转移到 match
或 if let
头部表达式:
let array = [Some(NonCopy), Some(NonCopy)];
if let [Some(_x), Some(_y)] = { array } {}
解释
借用检查器的当前实现是基于 AST 的,而 future 的实现将是基于 MIR 的。在高层次上,您可以将其视为“在我键入代码时处理代码”(AST) 和“在我的代码中处理数据的逻辑流”(MIR)。
某些“hacks”已被添加到 AST 借用检查器中,这就是为什么您可以成功使用数组文字而不是变量的原因。有了 MIR 借用检查器,像这样的更大的 hack 将消失,借用检查器也将变得更加精确,从而允许编译更多代码。
关于rust - 为什么我可以直接匹配一个Options数组而不是一个包含Options数组的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51005930/