我试图让示例代码尽可能简单
struct Level;
pub struct GameManager<'self>{
lvl: Level,
actors: ~[Actor<'self>]
}
struct Actor<'self>{
lvl: &'self Level
}
impl<'self> GameManager <'self> {
pub fn new() -> GameManager{
GameManager {lvl: Level,actors: ~[]}
}
fn spawn_actor<'r>(&'r self) -> Actor<'r>{
Actor{lvl: &'r self.lvl}
}
}
fn main() {
let mut gm = GameManager::new();
let mut actor1 = gm.spawn_actor();
gm.actors.push(actor1);
}
错误:
/home/maik/source/test.rs:23:4: 23:13 error: cannot borrow `gm.actors` as mutable because it is also borrowed as immutable
/home/maik/source/test.rs:23 gm.actors.push(actor1);
^~~~~~~~~
/home/maik/source/test.rs:21:21: 21:23 note: second borrow of `gm.actors` occurs here
/home/maik/source/test.rs:21 let mut actor1 = gm.spawn_actor();
如你所见,我希望GameManager产生一个演员。 GameManager作为一个级别,我希望所有衍生的演员都能参考GameManager的等级。
有人可以向我解释这个错误吗?我该如何解决?
答案 0 :(得分:3)
似乎在Rust中不可能。
但是我找到了一个解决方案来做到这一点,我只需要再封装一下,比如
struct Level;
pub struct ActorController{
lvl: Level
}
pub struct GameManager<'self>{
actors: ~[Actor<'self>],
actor_controller: ActorController
}
struct Actor<'self>{
lvl: &'self Level
}
impl ActorController {
fn spawn_actor<'r>(&'r self) -> Actor<'r>{
Actor{lvl: &'r self.lvl}
}
}
impl<'self> GameManager <'self> {
pub fn new() -> GameManager{
GameManager {actors: ~[], actor_controller: ActorController{lvl: Level}}
}
}
fn main() {
let mut gm = GameManager::new();
let actor1 = gm.actor_controller.spawn_actor();
gm.actors.push(actor1);
}
答案 1 :(得分:2)
你在Actor中有一个不可变的借用gm,只要它存在就不能修改它。
您可以将其更改为const借用,如:
struct Actor<'self>{
lvl: &'self const Level
}
但是我不确定它会在下次生锈时仍然存在。 (他们试图至少在编译器中摆脱它)
另一种选择是使用@ -pointers。那么你将不会有借款问题:)
编辑:这是使用const编译的整个代码
struct Level;
pub struct GameManager<'self>{
lvl: Level,
actors: ~[Actor<'self>]
}
struct Actor<'self>{
lvl: &'self const Level
}
impl<'self> GameManager <'self> {
pub fn new() -> GameManager{
GameManager {lvl: Level,actors: ~[]}
}
fn spawn_actor<'r>(&'r const self) -> Actor<'r>{
Actor{lvl: &'r const self.lvl}
}
}
fn main() {
let mut gm = GameManager::new();
let mut actor1 = gm.spawn_actor();
gm.actors.push(actor1);
}