是否有一种优雅的解决方案可以在迭代时修改结构?
Is there an elegant solution to modifying a structure while iterating?
我正在尝试构建一个点向量,这些点在遍历它们时会发生变化:
struct Point {
x: i16,
y: i16,
}
fn main() {
let mut points: Vec<Point> = vec![];
// unsure if point is mutable
points.push(Point { x: 10, y: 10 });
// thus trying it explicitly
let mut p1 = Point { x: 20, y: 20 };
points.push(p1);
for i in points.iter() {
println!("{}", i.x);
i.x = i.x + 10;
}
}
编译时出现错误:
error[E0594]: cannot assign to immutable field `i.x`
--> src/main.rs:16:9
|
16 | i.x = i.x + 10;
| ^^^^^^^^^^^^^^ cannot mutably borrow immutable field
据我了解 here,Rust 不允许在迭代结构时修改结构,因此出现错误。
如何优雅地修改它?如果我阅读 this answer 并正确理解,那么我会想到以下内容:
- 从向量中弹出项目,对其进行修改并将其推回。
- 创建一个临时结构,我将更改的项目推送到其中,并用循环外的临时结构替换原始结构(如何?)。
虽然我认为我可以让 (1) 工作,但我对所有这些 pop 和 push 并不是很满意(无论如何这是高性能吗?)。关于 (2),我不知道如何让它工作——如果它能工作的话。
问题:
- (2) 是一个解决方案吗?如果是,它会是什么样子?
- 还有其他解决方案吗?
- 不同解决方案的优点或缺点是什么,尤其是在性能方面?
您不能修改正在迭代的结构,即向量 points
。但是,修改从迭代器中获取的元素是完全没有问题的,您只需要选择可变性:
for i in points.iter_mut() {
或者,使用更现代的语法:
for i in &mut points {
可变性是可选的,因为可变的迭代进一步限制了你在迭代时可以用 points
做什么。由于可变别名(即两个或多个指向同一内存的指针,其中至少一个是 &mut
)是被禁止的,你甚至不能 read from points
而 iter_mut()
迭代器在附近。
我正在尝试构建一个点向量,这些点在遍历它们时会发生变化:
struct Point {
x: i16,
y: i16,
}
fn main() {
let mut points: Vec<Point> = vec![];
// unsure if point is mutable
points.push(Point { x: 10, y: 10 });
// thus trying it explicitly
let mut p1 = Point { x: 20, y: 20 };
points.push(p1);
for i in points.iter() {
println!("{}", i.x);
i.x = i.x + 10;
}
}
编译时出现错误:
error[E0594]: cannot assign to immutable field `i.x`
--> src/main.rs:16:9
|
16 | i.x = i.x + 10;
| ^^^^^^^^^^^^^^ cannot mutably borrow immutable field
据我了解 here,Rust 不允许在迭代结构时修改结构,因此出现错误。
如何优雅地修改它?如果我阅读 this answer 并正确理解,那么我会想到以下内容:
- 从向量中弹出项目,对其进行修改并将其推回。
- 创建一个临时结构,我将更改的项目推送到其中,并用循环外的临时结构替换原始结构(如何?)。
虽然我认为我可以让 (1) 工作,但我对所有这些 pop 和 push 并不是很满意(无论如何这是高性能吗?)。关于 (2),我不知道如何让它工作——如果它能工作的话。
问题:
- (2) 是一个解决方案吗?如果是,它会是什么样子?
- 还有其他解决方案吗?
- 不同解决方案的优点或缺点是什么,尤其是在性能方面?
您不能修改正在迭代的结构,即向量 points
。但是,修改从迭代器中获取的元素是完全没有问题的,您只需要选择可变性:
for i in points.iter_mut() {
或者,使用更现代的语法:
for i in &mut points {
可变性是可选的,因为可变的迭代进一步限制了你在迭代时可以用 points
做什么。由于可变别名(即两个或多个指向同一内存的指针,其中至少一个是 &mut
)是被禁止的,你甚至不能 read from points
而 iter_mut()
迭代器在附近。