rust - 引用和生命周期

标签 rust

我刚开始尝试使用 Rust,并想将这个简单的 C++ 程序转换为 Rust:

#include <iostream>
#include <vector>
#include <stdint.h>

using namespace std;

struct Game;

struct Player {
  Player(Game* game, uint32_t health) : game(game), health(health) {
  }

  uint32_t health;
  Game* game;
};

struct Game {
  Player& new_player() {
    players.emplace_back(this, 100);
    return players.back();
  }

  vector<Player> players;
};


int main() {
  Game g;
  g.new_player().health -= 10;
  g.new_player().health -= 20;

  for (auto p : g.players) {
    cout << "player health = " << p.health << endl;
  }

  return 0;
}

这是我对 Rust 的骇人听闻的尝试:

struct Player<'a> {
  health: i32,
  game: &'a mut Game<'a>
}

struct Game<'a> {
  players: Vec<Player<'a>>
}

impl <'a> Game<'a> {
  fn new() -> Game<'a> {
    Game { players: Vec::new() }
  }

  fn new_player(&'a mut self) -> &'a mut Player<'a> {
    unsafe {
      // Ugly unsafe hack to fix compiler error
      let ps: *mut Game<'a> = self;
      self.players.push(Player { health: 100, game: &mut *ps });
      self.players.mut_last().unwrap()
    }
  }
}

fn main() {
  let mut g = Game::new();
  g.new_player().health -= 10;

  // Compiler error about multiple borrows
  g.new_player().health -= 20;

  // Compiler error about multiple borrows
  for p in g.players.mut_iter() {
    println!("player health = {}", p.health);
  }
}

但是我使用了不安全的代码(我希望这不是必需的)并且遇到了引用和生命周期方面的问题,我真的不知道如何解决。在 Rust 中编写此代码的惯用方式是什么?或者 Rust 类型系统目前是否过于有限,无法以安全的方式表达它?

顺便说一句,我正在使用“rustc 0.12.0-pre-nightly (6bb72600c 2014-08-05 00:01:28 +0000)”。

最佳答案

同时拥有对一个对象的多个可变引用是不合理的,但你已经在你的不安全代码中导致了这种情况发生。这是一个等待发生的内存安全错误,因为您已经破坏了有关可变引用的不变量。

如果你希望能够从多个地方访问它,你需要使用像<a href="http://doc.rust-lang.org/std/rc/struct.Rc.html" rel="noreferrer noopener nofollow">Rc</a><<a href="http://doc.rust-lang.org/std/cell/struct.RefCell.html" rel="noreferrer noopener nofollow">RefCell</a><Game>>这样的东西。 (使 Player 中的一个成为 Weak<RefCell<Game>> ),并且您仍然需要确保在运行时不会对底层 Game 进行两个可变引用。一次。

如果可以避免存储对 Game 的引用的需要在Player ,这也能解决问题。

关于rust - 引用和生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25284837/

相关文章:

rust - “error: expected item, found ' 让 '”

rust - 引用向量中的元素

rust - 选择动态创建的 channel

rust - Serde Deserializer,如何在直接解码 `u8`和在 `u8`中解码 `Vec<u8>`时具有独特的行为

multithreading - 在多线程中使用没有 Arc 的 Mutex 是否安全?

rust - 如何证明类型中毒?

rust - 如何在 Rust 中 fork/exec 转发所有参数的进程?

c - 为什么必须在rust中初始化结构?

rust - 如果返回类型是通用的,我可以返回 &str 输入的切片吗?

windows - 使用SDL2 crate 运行和构建程序时出现问题