rust - 为什么我可以直接匹配一个Options数组而不是一个包含Options数组的变量?

标签 rust

编译以下代码:

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 时按原样工作.

坏消息

非词汇生命周期还不稳定。

解决方法

将数组的所有权显式转移到 matchif 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/

相关文章:

rust - 我可以借用一个指向 Rust 中共享特征的指针吗?

return - 为什么提早归还未完成未偿还的借贷?

rust - 从 getter 返回的 Struct 中窃取私有(private)成员

reference - 为什么 find 闭包的参数需要两个 & 符号?

Rust Shr 运算符

rust - 为什么类型推断在存在类型参数默认值的情况下对 `HashMap` 和我自己的结构表现不同?

rust - 为什么在变量上调用方法会阻止 Rust 推断变量的类型?

pattern-matching - 在模式匹配期间防止 move 语义

rust - Mio 在持续时间为零的投票中的行为是什么?

Rust 关闭工厂函数