2
struct Level{
    i_vec: ~[int]
}
pub struct GameManager{
    lvl: Level
}
impl GameManager {
    pub fn new() -> GameManager{
        GameManager {lvl: Level{i_vec: ~[]}}
    }
    pub fn new_game(f: ~fn()) {
        do spawn {
            f();
        }
    }
    pub fn default_game_loop(lvl: &Level ,f: &fn() ){
        loop {
            f();
            break;
        }
    }
}
fn main() {
    let mut gm = GameManager::new();
    do GameManager::new_game(){
        // I know I could move "gm" here, but I would like
        // to know how to capture mutable variables.
        do GameManager::default_game_loop(&gm.lvl){

        }
    }

}
/*
/home/maik/source/test.rs:28:43: 28:45 error: mutable variables cannot be implicitly captured
/home/maik/source/test.rs:28         do GameManager::default_game_loop(&gm.lvl){
                                                                        ^~
error: aborting due to previous error
[Finished in 0.2s with exit code 101]
*/

変更可能な変数をキャプチャするにはどうすればよいですか?

私もこれらの関数のメソッドを作成しようとしましたが、クロージャのように自分自身を移動しようとしたため、すべてが壊れました

do gm.default_game_loop(){
    let level = &gm.lvl;    
}

使用できる自己パラメーターはありますか? gm 自体はクロージャーのように利用できるはずなので

do gm.default_game_loop(){
        let level = self.lvl;    
}
4

1 に答える 1

1

あなたが直面している問題は、2 つのタスク間でメモリを直接共有できないことです。これを処理する従来の方法は、データをスレッドに移動することです。次に例を示します。

use std::task;

struct Level {
    i_vec: ~[int]
}
pub struct GameManager {
    lvl: Level
}
impl GameManager {
    pub fn new() -> GameManager {
        GameManager { lvl: Level { i_vec: ~[] } }
    }
    pub fn new_game<A: Send>(a: A, f: ~fn(A)) {
        task::spawn_with(a, f)
    }
    pub fn default_game_loop(lvl: &Level, f: &fn()) {
        loop {
            f();
            break;
        }
    }
}
fn main() {
    let mut gm = GameManager::new();
    do GameManager::new_game(gm) |gm| {
        // I know I could move "gm" here, but I would like
        // to know how to capture mutable variables.
        do GameManager::default_game_loop(&gm.lvl) {

        }
    }
}

変更可能な状態を複数のスレッドで共有する必要がある場合は、もう少し注意が必要です。これを行うには、変更可能な状態を所有するタスクをセットアップし、変更はstd::comm::streamチャネルを介して、またはミューテックスで保護されたextra::arc::RWArcを介して行われます。

于 2013-08-20T03:28:09.170 に答える