我想学习Rust,但是我一直试图把我熟悉的Java概念硬塞到它的类型系统中,或者尝试硬塞Haskell概念等等,结果只是不停地碰壁。
我想写一个有玩家和多个资源的游戏。每个资源都可以被一个玩家所拥有:
struct Player {
points: i32,
}
struct Resource<'a> {
owner: Option<&'a Player>,
}
fn main() {
let mut player = Player { points: 0 };
let mut resources = Vec::new();
resources.push(Resource {
owner: Some(&player),
});
player.points = 30;
}
它无法编译,因为我不能将资源指向玩家,同时又修改它:
error[E0506]: cannot assign to `player.points` because it is borrowed
--> src/main.rs:15:5
|
13 | owner: Some(&player),
| ------ borrow of `player.points` occurs here
14 | });
15 | player.points = 30;
| ^^^^^^^^^^^^^^^^^^ assignment to borrowed `player.points` occurs here
此外,如果Resource
拥有对Player
的可变引用,我甚至无法拥有两个拥有相同所有者的Resource
。
在Rust中解决这种情况的方法是什么?
我过于简化了我的问题,虽然Shepmaster的答案是正确的答案,但它不是我想要得到的(因为我所问的并不是我真正想问的)。我将尝试重新表述并添加更多上下文。
- 这些资源以某种方式相互连接 - 所有资源的映射形成了一个(非)定向图。
- 每个玩家可以拥有许多资源,每个资源只能被一个玩家拥有。玩家应该能够从他们拥有的资源中获得积分。我想到了一个签名,类似于:
fn addPoints(&mut self, allResources: &ResourcesMap) -> ()
。 - 玩家可以接管与他们的某个资源相连的资源,而这些资源原属于另一个玩家。这可能会导致其他玩家失去一些积分。
问题:
- 如何在Rust中表示这样的图形(可能是循环结构,每个节点可以从许多节点指向)?
- 最初的问题:如果
Resource
指向一个Player
,我无法修改该玩家!
Resource
之所以指向Player
,是因为 - 执行这种操作的自然方式将从A玩家的某些资源开始,通过地图移动到玩家B的资源,然后从该资源到达玩家B以减去积分。对我来说,这似乎在Rust中并不自然。