有如下代码:
fn main() {
let msg = Message::Hello { id: 110 };
match msg {
x @ Message::Hello { id } => println!("{} in {:?}", id, x),
_ => println!("world"),
}
}
#[derive(Debug)]
enum Message {
Hello { id: i32 },
// World { a: i32, b: i32 },
}
我把World那一行注释了,可以编译通过。但是如果取消注释,那就有会报错,错误如下:
--> src\main.rs:5:30
|
2 | let msg = Message::Hello { id: 110 };
| --- move occurs because `msg` has type `Message`, which does not implement the `Copy` trait
...
5 | x @ Message::Hello { id } => println!("{} in {:?}", id, x),
| - value moved here ^^ value used here after move
|
help: borrow this binding in the pattern to avoid moving the value
|
5 | ref x @ Message::Hello { id } => println!("{} in {:?}", id, x),
| +++
请教下这是什么原因?为什么enum里有多个时,会有move的问题。
1
共 6 条评论, 1 页
评论区
写评论如果你交叉发布相同的问题到 URLO,请附上链接。
Confusing @ Pattern matching
#90368: 2021 edition's binding to sub-pattern doesn't work on enum with copyable fields
我猜可能会有一些考量:回看
copy, single variant
生成的 MIR,会发现Message { id }
对应于_3 = ((_1 as Hello).0: i32)
,这与结构体的模式匹配很类似而双(多) variant 下,首先会识别判别式 (discriminant),即不像
(_1 as Hello)
那么简单,然后才 move 到 x,最后进行其他操作。如果你觉得这是一个问题,就去 Rust 仓库找 issue 或者在那提问。
其实我对这句有点儿不太理解,或者说不太容易接收,我总感觉这改变了语义。
都是
Copy
的,却按non-copy
处理,而且单variant和双variant语义还不一致--
👇
araraloren: 这看起来应该是个bug,经过分析感觉加了
World
之后生成代码的顺序变了这看起来应该是个bug,经过分析感觉加了
World
之后生成代码的顺序变了谢谢,涨知识了
--
👇
苦瓜小仔: > 为什么enum里有多个时
与 variant 数量无关,只把 id 换成 String (非 Copy 类型),一样报错
问题出在单 variant 对 Copy 类型的处理不同, 关键的 MIR 代码:
首先,不要依赖上面对 Copy vs non-Copy 脱糖的细节。
其次,查看 MIR 后,对双 variant 下的 id(: i32) 的处理类似于
non-copy, single variant
的情况,所以出错:即移动 msg 所有权之后移动 id 的所有权导致错误。最后,在双 variant 下 Copy id 之后移动 msg 所有权的一种做法是:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=94790f2b7994651e68ab9d9eba480ce8
与 variant 数量无关,只把 id 换成 String (非 Copy 类型),一样报错
问题出在单 variant 对 Copy 类型的处理不同, 关键的 MIR 代码:
首先,不要依赖上面对 Copy vs non-Copy 脱糖的细节。
其次,查看 MIR 后,对双 variant 下的 id(: i32) 的处理类似于
non-copy, single variant
的情况,所以出错:即移动 msg 所有权之后移动 id 的所有权导致错误。最后,在双 variant 下 Copy id 之后移动 msg 所有权的一种做法是:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=94790f2b7994651e68ab9d9eba480ce8