提问人:Nawaz 提问时间:7/25/2022 最后编辑:Nawaz 更新时间:7/25/2022 访问量:163
是否有可能同时进行可变绑定和解构?
Is it possible to have mutable binding and destructuring simultaneously?
问:
下面的代码按预期工作(演示),但这需要两个嵌套,我只想用一个替换。match {}
#![allow(unused)]
use std::collections::hash_map::HashMap;
#[derive(Debug, Clone)]
struct NormalTransaction(f64);
// only normal transaction can be disputed.. BY DESIGN
#[derive(Debug, Clone)]
struct DisputeTransaction(NormalTransaction);
#[derive(Debug, Clone)]
enum Transaction {
Normal(NormalTransaction),
Dispute(DisputeTransaction),
}
fn main() {
let mut m = HashMap::new();
m.insert(1, Transaction::Normal(NormalTransaction(100.0)));
println!("before: {:#?}", m);
match m.get_mut(&1) {
Some(t) => match t {
Transaction::Normal(normal) => {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
_ => {}, // NA
}
_ => {}, // NA
}
println!("after: {:#?}", m);
}
仅将两者替换为一个,如下所示:match{}
match m.get_mut(&1) {
Some(t @ Transaction::Normal(normal)) => {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
_ => {}, // NA
}
但它不起作用,说(演示):
error: borrow of moved value
--> src/main.rs:24:14
|
24 | Some(t @ Transaction::Normal(normal)) => {
| -^^^^^^^^^^^^^^^^^^^^^^^------^
| | |
| | value borrowed here after move
| value moved into `t` here
| move occurs because `t` has type `&mut Transaction` which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> src/main.rs:24:38
|
24 | Some(t @ Transaction::Normal(normal)) => {
| ------------------------^^^^^^-
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `&mut Transaction`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving the value
|
24 | Some(ref t @ Transaction::Normal(normal)) => {
| +++
是否可以在单个匹配情况下进行可变绑定和解构?
答:
2赞
orlp
7/25/2022
#1
我不知道使用单个匹配项的方法,但如果您使用 s 而不是匹配项,它看起来并不那么糟糕:if let
if let Some(t) = m.get_mut(&1) {
if let Transaction::Normal(normal) = t {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
}
一旦 let-chains 落地,我相信你也应该会写
if let Some(t) = m.get_mut(&1) && let Transaction::Normal(normal) = t {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
评论
0赞
Nawaz
7/25/2022
是的。这就是我在发布问题后所写的。这似乎更好,特别是因为我不关心两个匹配表达式中的情况。所以代码更少!else
0赞
Nawaz
7/25/2022
顺便说一句,你忘记了 let-chains 代码中的第二个吗?还是不需要?let
1赞
orlp
7/25/2022
@Nawaz我只是忘记了,修复了。
0赞
Nawaz
8/2/2022
在没有更好的答案的情况下,我现在接受这个答案!
评论
@
@