向量中的可变结构

时间:2014-05-10 19:55:05

标签: 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, "$", 10, 1, "")
 enemies.push(enemy);

稍后在代码中我从enemies中挑出一个敌人进行攻击并尝试更新hp,如下所示:

  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`

2 个答案:

答案 0 :(得分:10)

针对最新的Rust版本进行了更新

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

let mut world = World::new();

然后你可以对这个变量进行可变引用,从而调用可以改变它的方法。

您的结构拥有它包含的所有数据,因此您可以随时使其变为可变。 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;
  }
}

请注意,为了使其正常工作,您必须通过可变引用传递self,否则将无法改变其下的任何内容,这意味着您将无法获取可变引用结构的内部,包括向量的项目。简而言之,确保包含此循环的任何方法都定义如下:

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

答案 1 :(得分:0)

Vec<T>::iter()给你一个Iterator<&T> 1 ,即一个迭代器超过&#34;不可变借用&#34;指针。如果您想改变内容,请使用Vec::iter_mut()Iterator<&mut T>

一般情况下,mut的存在与否会影响是否可以使用某种方法,但不会影响每种方法的含义。这不是全部真相(也许&&mut实现了同名方法的不同特征,但它是一个很好的近似值。

1 为了说明这一点,我省略了这些类型的生命周期方面。