繁体   English   中英

参考和寿命

[英]References and lifetimes

我刚刚开始对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)”。

听起来对一个对象有多个可变的引用是不可行的,但是这是在不安全的代码中引起的。 这是一个等待发生的内存安全错误,因为您已经打破了关于可变引用的不变性。

如果您希望能够从多个位置访问它,则需要使用Rc < RefCell <Game>> (将Player内部的一个设置为Weak<RefCell<Game>> ),并且仍然需要以确保在运行时不会一次对基础Game进行两个可变的引用。

如果您可以避免在Player存储对Game的引用,那也可以解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM