2013-08-09 4 views
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;  
} 

ответ

1

Проблема, с которой вы сталкиваетесь, заключается в том, что вы не можете напрямую обмениваться памятью между двумя задачами. Традиционным способом обработки данных является перемещение данных в поток. Вот пример:

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 или через защищенный mutex extra::arc::RWArc.