rust - 使用可变迭代器进行迭代时对不可变借用执行操作
问题描述
这是一个简单的人工示例来说明问题:
fn sum_slice(v: &[i32]) -> i32 {
v.iter().sum()
}
fn sum_previous(v: &mut [i32]) {
for (i, val) in v.iter_mut().enumerate() {
*val = sum_slice(&v[0..i]);
}
}
fn main() {
let mut v = vec![1,1,1,1,1,1,1];
sum_previous(&mut v);
println!("{:?}", v);
}
理想情况下,目的是sum_previous
获取提供的切片并将每个元素替换为先前元素的总和。
但这会产生错误:
error[E0502]: cannot borrow `*v` as immutable because it is also borrowed as
mutable
--> src/main.rs:7:27
|
6 | for (i, val) in v.iter_mut().enumerate() {
| ------------------------
| |
| mutable borrow occurs here
| mutable borrow later used here
7 | *val = sum_slice(&v[0..i]);
| ^ immutable borrow occurs here
我理解 Rust 限制我们同时拥有一个可变引用和不可变引用的问题。我也可以提供不同的解决方案,例如使用另一个向量来存储结果,但问题不是如何解决它,而是这里可以接受的模式是什么?
FWIW 最初的问题是元胞自动机的实现,其中要处理一个网格,并且每个单元都要根据其邻居进行更新。在这种情况下,网格是可变借用的,而计算更新的函数需要一个不可变的引用。
解决方案
您可以使用以下方法执行此操作split_at_mut
:
fn sum_previous(v: &mut [i32]) {
for i in 1..v.len() {
let (head, tail) = v.split_at_mut(i);
tail[0] = sum_slice(head);
}
}
(永久链接到操场)
推荐阅读
- sql - 在 SQL 上,我想按查询在表中出现的次数过滤查询
- r - dplyr 基于数据类型的条件变异
- flutter - 动态路由颤动
- postgresql - 尝试 json_agg 多个列会引发错误“没有函数与给定名称匹配...”
- r - Quanteda 按多个变量对文档进行分组
- javascript - 如何在不丢失索引的情况下过滤数组?
- javascript - 如何使用 id 为对象内的两个不同数组应用条件
- javascript - Javascript中的TypeError SpreadJS
- python - 如何使用 Numba 附加 String Int 和 Float 类型的列表
- r - 抑制自定义语言引擎中 knitr 块选项的评估