rust - How to reference multiple members in an array? -


i have array of 2 players. have variable, current_num equal player in array current player. have while loop iterates through main game logic current_num updated, stays same. assigned current_player , next_player variable each iteration of loop so:

while !self.board.check_win() {    let ref mut current_player = self.players[current_num];    let ref mut next_player = self.players[(current_num+1)%2];    /* game logic */ } 

this doesn't work because try borrow self.players[..] twice. don't need next_player variable if somehow store next player inside first player object, can't create cyclic data structures in rust seems. fought hard compiler accomplish following:

player1.next = &player2; player2.next = &player1; 

unfortunately doesn't seem possible.... if is, rather along lines of:

current_player.next().do_something(); 

instead of needing next_player variable. able do:

current_player = current_player.next(); 

for switching next player wouldn't have keep index variable (current_num).

now have working mode refer current player as:

self.players[current_num].do_something()       //current_player self.players[(current_num+1)%2).do_something() //next_player 

this avoids borrowing issues, makes verbose code that's hard read. c/c++ easier regards getting kind of design working. feel i'm fighting compiler want done...

any appreciated!

to solve immediate problem can use the mut_split_at method, uses unsafe code internally give 2 disjoint slices vector, resolving borrowing issues. might write wrapper like:

fn double_index<'a, t>(x: &'a mut [t],                        i: uint, j: uint) -> (&'a mut t, &'a mut t) {     assert!(i != j, "cannot double_index equal indices");      if < j {         let (low, hi) = x.mut_split_at(j);          (&mut low[i], &mut hi[0])     } else { // > j         let (low, hi) = x.mut_split_at(i);          (&mut hi[0], &mut low[j])     } } 

then write

let (current_player, next_player) = double_index(self.players,                                                  current_num,                                                  (current_num + 1) % 2); 

(assuming self.players [player, .. 2] or &mut [player]. if vec<player> need call .as_mut_slice() explicitly.)


you can't create cyclic data structures in rust seems

you can, using rc , weak. shared mutability, you'll need use refcell or cell. e.g.

use std::rc::{rc, weak}; use std::cell::refcell;  struct player {     // ...     next: option<weak<refcell<player>>> }  impl player {     fn next(&self) -> rc<refcell<player>> {          // upgrade goes weak rc & fails if invalid          self.next.unwrap().upgrade()     } }  let player1 = rc::new(refcell::new(player { ..., next: none })); let player2 = rc::new(refcell::new(player { ..., next: none }));  // join them up; downgrade goes rc weak player1.borrow_mut().next = some(player2.downgrade()); player2.borrow_mut().next = some(player1.downgrade()); 

this avoids borrowing issues, makes verbose code that's hard read. c/c++ easier regards getting kind of design working. feel i'm fighting compiler want done...

any sort of shared mutability easy wrong; , in languages without gc, can lead dangling pointers, segfaults & security holes. unfortunately sealing holes in manner rust leads type of thing being rather ugly @ times.


Comments

Popular posts from this blog

android - Automated my builds -

how to proxy from https to http with lighttpd -

python - Flask migration error -