带有向量的可变匹配可变枚举引用

问题描述 投票:0回答:1

我正在尝试更改枚举的命名属性,但出现此错误。

cannot move out of a mutable referencerustc(E0507)
parser.rs(323, 36): data moved here
parser.rs(323, 36): move occurs because `statements` has type `std::vec::Vec<std::boxed::Box<ast::ast::StatementType>>`, which does not implement the `Copy` trait

我看到我们可以使用match语句更改枚举的命名道具。但是我不明白为什么会发生移动,因为我是在借用枚举本身。这是代码:

        match &mut block {
            StatementType::Block { mut statements, .. } => {
                statements = block_statements;
            },
            _ => panic!()
        };
        return block;

我也尝试过mem :: swap,但仍然是相同的错误:

        match &mut block {
            StatementType::Block { mut statements, .. } => {
                // statements = block_statements;
                std::mem::swap(&mut statements, &mut block_statements);
            },
            _ => panic!()
        };
        return block;

BUT当我这样做时:

                std::mem::swap(&mut *statements, &mut *block_statements);

错误变为:

the size for values of type `[std::boxed::Box<ast::ast::StatementType>]` cannot be known at compilation time

doesn't have a size known at compile-time

类型是:

  • StatementType是派生Clone的枚举
  • 块是StatementType的可变变量
  • 块的statementsVec<Box<StatementType>>的变量
  • [block_statementsVec<Box<StatementType>>的另一个变量

请不要说发生这种情况是因为语句的类型是Vector:提供解决方案,因为我也可以读取错误消息。

vector enums rust move
1个回答
0
投票

您必须考虑statements的类型是什么以及您希望它是什么。

[使用您编写的代码,它的类型为Vec<_>(对不起,我说过),但由于match通过引用捕获块,因此无法按值获取内容,因此会出现错误。请注意,错误不在赋值中,而在匹配括号中:

error[E0507]: cannot move out of a mutable reference
  --> src/main.rs:15:11
   |
15 |     match &mut block {
   |           ^^^^^^^^^^
16 |         StatementType::Block { mut statements, .. } => {
   |                                --------------
   |                                |
   |                                data moved here
   |                                move occurs because `statements` has type `std::vec::Vec<std::boxed::Box<StatementType>>`, which does not implement the `Copy` trait

您当然希望statement的类型为&mut Vec<_>。如果您利用匹配人体工程学的优势,那么您会得到:

    match &mut block {
        StatementType::Block { statements, .. } => {
            *statements = block_statements;
        },
        _ => panic!()
    };

并且请记住在分配时使用*statement,因为它现在是参考。当然,您也可以使用mem::swap

            std::mem::swap(statements, &mut block_statements);

为了完成,没有匹配人体工程学的语法将是:

    match block {
        StatementType::Block { ref mut statements, .. } => {
            *statements = block_statements;
        },
        _ => panic!()
    };

通过匹配&mut block而不是block,您无需指定ref mut验证模式,但是如果您指定任何捕获模式,则将禁用匹配人体工程学。您可以只在代码中添加ref,它也可以工作,但是我认为最好删除mut并让编译器发挥作用。

© www.soinside.com 2019 - 2024. All rights reserved.