本文介绍了向量中的可变结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to create a vector to keep track of enemies in a game that will hold a bunch of mutable structs. I have a world struct that has the enemies as a member of it as follows:

pub struct World {
  pub player      : Creature,
  pub enemies     : Vec<Creature>,
}

我按如下方式创建敌人向量:

I create the enemies vector as follows:

 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 时:

later on in the code when I pull out an individual enemy from enemies for attacking and try to update the hp as follows:

  for enemy in self.enemies.iter() {
    if new_x == enemy.x && new_y == enemy.y {
      enemy.hp -= self.player.damage;
      return;
    }
  }

这是出现问题的地方,因为此时敌人显然不可变

which is where the problem occurs since enemy is apparently not mutable at this point

 error: cannot assign to immutable field `enemy.hp`

推荐答案

更新到最新的 Rust 版本

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

Mutability in Rust is not associated with data structures, it is a property of a place (read: a variable) where the data is stored. That is, if you place a value in a mutable slot:

let mut world = World::new();

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

then you can take mutable references to this variable, and hence call methods which can mutate it.

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

Your structure owns all data it contains, so you can make it mutable any time you need. self.enemies.iter() returns an iterator which generates items of type &Creature - immutable references, so you can't use them to mutate the structure. However, there is another method on a vector, called iter_mut(). This method returns an iterator which produces &mut Creature - mutable references, which do allow changing data they point to.

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,否则它下面的任何东西都不可能发生变异,这意味着你将无法获得对结构内部的可变引用,包括向量的项.简而言之,确保任何包含此循环的方法都像这样定义:

Note that in order for this to work, you have to pass self by mutable reference too, otherwise it will be impossible to mutate anything under it, implying that you won't be able to obtain mutable references to internals of the structure, including items of the vector. In short, make sure that whatever method contains this loop is defined like this:

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

这篇关于向量中的可变结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 10:49