Lin*_*y B 10 struct vector rust
我正在尝试创建一个矢量来跟踪游戏中的敌人,这些游戏将拥有一堆可变结构.我有一个世界结构,其敌人作为其成员如下:
pub struct World {
pub player : Creature,
pub enemies : Vec<Creature>,
}
Run Code Online (Sandbox Code Playgroud)
我按如下方式创建敌人矢量:
let mut enemies = vec![];
let mut enemy = Creature::new(5, 5, map_start_x+5, map_start_y+5, "$", 10, 1, "")
enemies.push(enemy);
Run Code Online (Sandbox Code Playgroud)
后来我在代码中拔出一个敌人enemies进行攻击并尝试更新hp,如下所示:
for enemy in self.enemies.iter() {
if new_x == enemy.x && new_y == enemy.y {
enemy.hp -= self.player.damage;
return;
}
}
Run Code Online (Sandbox Code Playgroud)
这是问题发生的地方,因为此时敌人显然不可变
error: cannot assign to immutable field `enemy.hp`
Run Code Online (Sandbox Code Playgroud)
Vla*_*eev 11
更新了最新的Rust版本
Rust中的可变性与数据结构无关,它是存储数据的地方(读取:变量)的属性.也就是说,如果您在可变插槽中放置一个值:
let mut world = World::new();
Run Code Online (Sandbox Code Playgroud)
那么你可以对这个变量进行可变引用,从而调用可以改变它的方法.
您的结构拥有它包含的所有数据,因此您可以在需要时随时使其变为可变.self.enemies.iter()返回一个生成类型的项的迭代器&Creature- 不可变引用,因此您不能使用它们来改变结构.但是,在矢量上有另一种方法,称为iter_mut().此方法返回一个迭代器,它生成&mut Creature- 可变引用,它允许更改它们指向的数据.
for enemy in self.enemies.iter_mut() {
if new_x == enemy.x && new_y == enemy.y {
enemy.hp -= self.player.damage;
return;
}
}
// The following also works (due to IntoIter conversion)
for enemy in &mut self.enemies {
if new_x == enemy.x && new_y == enemy.y {
enemy.hp -= self.player.damage;
return;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,为了使其工作,你必须self通过可变引用,否则将无法改变其下的任何内容,这意味着你将无法获得对结构内部的可变引用,包括矢量.简而言之,确保包含此循环的任何方法都定义如下:
fn attack(&mut self, ...) { ... }
Run Code Online (Sandbox Code Playgroud)