Vector 向量中的可变结构

Vector 向量中的可变结构,vector,struct,rust,Vector,Struct,Rust,我试图创建一个向量来跟踪一个游戏中的敌人,这个游戏将包含一堆可变结构。我有一个世界结构,其中敌人是其中的一员,如下所示: pub struct World { pub player : Creature, pub enemies : Vec<Creature>, } let mut enemies = vec![]; let mut enemy = Creature::new(5, 5, map_start_x+5, map_start_y+5, "$

我试图创建一个向量来跟踪一个游戏中的敌人,这个游戏将包含一堆可变结构。我有一个世界结构,其中敌人是其中的一员,如下所示:

pub struct World {
  pub player      : Creature,
  pub enemies     : Vec<Creature>,
}
 let mut enemies = vec![];
 let mut enemy = Creature::new(5, 5, map_start_x+5, map_start_y+5, "$", 10, 1, "")
 enemies.push(enemy);
  for enemy in self.enemies.iter() {
    if new_x == enemy.x && new_y == enemy.y {
      enemy.hp -= self.player.damage;
      return;
    }
  }
稍后在代码中,当我从
敌人
中拉出一个单独的敌人进行攻击并尝试更新hp时,如下所示:

pub struct World {
  pub player      : Creature,
  pub enemies     : Vec<Creature>,
}
 let mut enemies = vec![];
 let mut enemy = Creature::new(5, 5, map_start_x+5, map_start_y+5, "$", 10, 1, "")
 enemies.push(enemy);
  for enemy in self.enemies.iter() {
    if new_x == enemy.x && new_y == enemy.y {
      enemy.hp -= self.player.damage;
      return;
    }
  }
这就是问题所在,因为敌人在这一点上显然是不可变的

 error: cannot assign to immutable field `enemy.hp`
Vec::iter()
提供了一个
迭代器
1,即“不可变借用”指针上的迭代器。如果要改变内容,请使用
Vec::iter_mut()
,这是一个
迭代器

一般来说,
mut
的存在与否会影响您是否可以使用某种方法,但不会影响每种方法的含义。这并不是全部事实(可能对
&
&mut
实现了同名方法的不同特征),但这是一个很好的近似值


1为了说明问题,我省略了这些类型的寿命方面。

更新了最新的锈迹版本

Rust中的易变性与数据结构无关,它是存储数据的位置(读取:变量)的属性。也就是说,如果在可变槽中放置值:

let mut world = World::new();
然后,您可以对该变量进行可变引用,从而调用可以对其进行变异的方法

您的结构拥有它包含的所有数据,因此您可以在需要时使其可变
self.friends.iter()
返回一个迭代器,该迭代器生成类型为
&bioter
-不可变引用的项,因此不能使用它们来改变结构。然而,向量上还有另一种方法,称为
iter\u mut()
。此方法返回一个迭代器,该迭代器生成
&mut biote
-可变引用,允许更改它们指向的数据

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;
  }
}
请注意,为了使其正常工作,您也必须通过可变引用传递
self
,否则就不可能对其下的任何内容进行变异,这意味着您将无法获得对结构内部的可变引用,包括向量项。简而言之,请确保包含此循环的任何方法的定义如下:

fn attack(&mut self, ...) { ... }

mut_iter()
做到了这一点(在我的例子中我不清楚,但我实际上是在传递
&mut self
):)注意
mut_iter
现在被称为
iter_mut
。注意
mut_iter
现在被称为
iter_mut