Rust 将可变枚举引用与向量匹配
Rust match mutable enum reference with vectors
我正在尝试更改枚举的 命名为 属性 但出现此错误。
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 &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;
但是 当我这样做时:
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 的枚举
- Block 是 StatementType 的可变变量
- 块的
statements
是Vec<Box<StatementType>>
的变量
block_statements
是Vec<Box<StatementType>>
的另一个变量
请不要说它会发生,因为语句的类型是 Vector:请提供解决方案,因为我也可以读取错误消息。
您必须考虑 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<_>
类型。您可以通过使用 ref mut
捕获模式获得它:
match block {
StatementType::Block { ref mut statements, .. } => {
*statements = block_statements;
},
_ => panic!()
};
并且记得在分配时使用 *statement
,因为它现在是一个引用。如果你愿意,你也可以使用 mem::swap
,当然:
std::mem::swap(statements, &mut block_statements);
但请注意,您不需要match &mut block
,但您可以直接match block
。
有一个叫做 match ergonomics 的东西可以让你匹配参考并省略 ref mut
捕获模式,这让你的代码更容易编写和理解:
match &mut block {
StatementType::Block { statements, .. } => {
*statements = block_statements;
},
_ => panic!()
};
您的原始代码中的问题是,如果指定任何捕获模式,则会禁用匹配人体工程学。
我正在尝试更改枚举的 命名为 属性 但出现此错误。
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 &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;
但是 当我这样做时:
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 的枚举
- Block 是 StatementType 的可变变量
- 块的
statements
是Vec<Box<StatementType>>
的变量
block_statements
是Vec<Box<StatementType>>
的另一个变量
请不要说它会发生,因为语句的类型是 Vector:请提供解决方案,因为我也可以读取错误消息。
您必须考虑 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<_>
类型。您可以通过使用 ref mut
捕获模式获得它:
match block {
StatementType::Block { ref mut statements, .. } => {
*statements = block_statements;
},
_ => panic!()
};
并且记得在分配时使用 *statement
,因为它现在是一个引用。如果你愿意,你也可以使用 mem::swap
,当然:
std::mem::swap(statements, &mut block_statements);
但请注意,您不需要match &mut block
,但您可以直接match block
。
有一个叫做 match ergonomics 的东西可以让你匹配参考并省略 ref mut
捕获模式,这让你的代码更容易编写和理解:
match &mut block {
StatementType::Block { statements, .. } => {
*statements = block_statements;
},
_ => panic!()
};
您的原始代码中的问题是,如果指定任何捕获模式,则会禁用匹配人体工程学。