rust - 重复更新和输出数据结构
问题描述
我有一个fruitlist: Vec<&mut Groceries>
不易复制的可变数据结构 ( )。我想反复更新和输出它。这是一个最小的例子:
// Note that Groceries do not implement the Copy trait
struct Groceries {
amount: u32,
item: String,
}
// takes mutable references because we will alter the Groceries
fn update_groceries(groceries: Vec<&mut Groceries>) {
// Double everything we have, just in case of a pandemic
for g in groceries {
g.amount *= 2;
}
}
// takes immutable references because we will only need to read them
fn output_groceries(groceries: Vec<&Groceries>) {
for g in groceries {
println!("{}: {}", g.item, g.amount);
}
}
fn main() {
// We start with a list of fruit
let mut bananas: Groceries = Groceries{amount:3, item: String::from("yellow bananas")};
let mut oranges: Groceries = Groceries{amount:2, item: String::from("oranges")};
let fruitlist: Vec<&mut Groceries> = vec![
&mut bananas,
&mut oranges,
];
// Now we want to update and print the list
update_groceries(fruitlist);
// the following line is necessary to get from Vec<&mut Groceries> to Vec<& Groceries>
let fruitlist_immutable_references: Vec<& Groceries> = fruitlist.into_iter().map(|x| &*x).collect();
output_groceries(fruitlist_immutable_references);
// This update and print part might happen multiple times in a loop.
}
这失败了,因为fruitlist
正在移动:
error[E0382]: use of moved value: `fruitlist`
--> src/main.rs:38:60
|
29 | let fruitlist: Vec<&mut Groceries> = vec![
| --------- move occurs because `fruitlist` has type `std::vec::Vec<&mut Groceries>`, which does not implement the `Copy` trait
...
36 | update_groceries(fruitlist);
| --------- value moved here
37 | // the following line is necessary to get from Vec<&mut Groceries> to Vec<& Groceries>
38 | let fruitlist_immutable_references: Vec<& Groceries> = fruitlist.into_iter().map(|x| &*x).collect();
| ^^^^^^^^^ value used here after move
当我注释掉更新时,代码工作正常。
我发现自己一次又一次地以不同的形式遇到这个问题。我怎样才能使这种模式起作用?或者有没有更好的方法来重复更新和输出复杂的数据结构?
(线定义fruitlist_immutable_references
也很丑。我希望有更好的方法)
解决方案
如果您将列表按值(例如list: Vec<&mut Groceries>
)传递给函数,那么它将列表的所有权转移到函数中。相反,您应该通过引用(例如list: &mut [&mut Groceries]
,或list: &[&Groceries]
)传递它以维护列表的所有权。固定示例:
// Note that Groceries do not implement the Copy trait
struct Groceries {
amount: u32,
item: String,
}
// takes mutable references because we will alter the Groceries
fn update_groceries(groceries: &mut [&mut Groceries]) {
// Double everything we have, just in case of a pandemic
for g in groceries {
g.amount *= 2;
}
}
// takes immutable references because we will only need to read them
fn output_groceries(groceries: &[&Groceries]) {
for g in groceries {
println!("{}: {}", g.item, g.amount);
}
}
fn main() {
// We start with a list of fruit
let mut bananas: Groceries = Groceries { amount:3, item: String::from("yellow bananas") };
let mut oranges: Groceries = Groceries { amount:2, item: String::from("oranges") };
let mut fruitlist: Vec<&mut Groceries> = vec![
&mut bananas,
&mut oranges,
];
// Now we want to update and print the list
update_groceries(&mut fruitlist);
// the following line is necessary to get from Vec<&mut Groceries> to Vec<& Groceries>
let fruitlist_immutable_references: Vec<&Groceries> = fruitlist.into_iter().map(|x| &*x).collect();
output_groceries(&fruitlist_immutable_references);
// This update and print part might happen multiple times in a loop.
}
推荐阅读
- python - 如何使 Async IO 在非异步函数上工作?
- python - 每次使用不同的数据集多次调用以及使用所有数据集调用一次时,keras 模型的拟合有何不同?
- kubernetes - 如何为资源配额 k8s 创建警报以发送警报,例如 Prometheus
- db2 - IBM Watson Db2 服务凭证创建错误
- html - CSS 过渡跳跃与最小宽度媒体查询
- java - Java 应用 Swing 绘制无 Snake
- javascript - 如何从 javascript 中的 C# HttpResponseMessage 读取内容?
- android - 旋转后软键盘消失
- swagger - 如何在 Sanic-openapi 中设置标签描述?
- angular - 使用指令 Angular 动态创建元素