我刚开始尝试使用 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/