借用'自我'来解决问题

时间:2013-08-09 04:36:33

标签: rust

我试图让示例代码尽可能简单

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的等级。

有人可以向我解释这个错误吗?我该如何解决?

2 个答案:

答案 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);
}