Rust trying to maintain self-defined list: cannot borrow `self.array` as mutable more than once at a time

80 Views Asked by At

I'm new to rust and trying to maintain 2 linked-list inside an array, my code goes like:

#[derive(Copy, Clone)]
struct Node {
    next: i32,
    prev: i32,
    val: i32
}

impl Node {

    pub fn new()->Self{
        Self{
            next: 0,
            val: 0,
            prev: 0
        }
    }
    pub fn get_prev(&self) -> i32{
        self.prev
    }

    pub fn get_next(&self) -> i32{
        self.next
    }

    pub fn set_prev(& mut self, idx: i32){
        self.prev = idx;
    }

    pub fn set_next(& mut self, idx: i32){
        self.next = idx;
    }

    pub fn get_val(&self)->i32{
        self.val
    }

    pub fn set_val(& mut self, v: i32){
        self.val = v;
    }
}

struct MyVec{
    red_start: i32,
    black_start: i32,
    data: [Node; 48]
}

impl MyVec{
    pub fn new()->Self{
        let mut ans = Self{
            red_start : -1,
            black_start: 0,
            data: [Node::new(); 48]
        };
        let len = ans.data.len();
        for i in 0..ans.data.len(){
            let n: & mut Node = & mut ans.data[i];
            n.set_prev(((i + len-1) % len) as i32);
            n.set_next(((i+1) % len) as i32);
        }
        ans
    }

    pub fn move_black_to_red(& mut self, idx: i32){
        let n: & mut Node = & mut self.data[idx as usize];
        let prev: & mut Node = & mut self.data[n.get_prev() as usize];
        let next: & mut Node = & mut self.data[n.get_next() as usize];
        prev.set_next(n.get_next());
        next.set_prev(n.get_prev());
        //other stuff...
    }
}

The difficulties are in move_black_to_red fucntion, I need to maintain this list, so I need to get 3 mut references at the same time and update them. However, there is at most 1 mut borrow from self, so what should I do?

1

There are 1 best solutions below

1
loops On BEST ANSWER

Rust doesn't allow multiple mutable references to the same variable at the same time. The easiest way to fix this would be to interleave the borrows, and borrow n immutably, since you never mutate it:

pub fn move_black_to_red(& mut self, idx: i32){
    let n: Node = self.data[idx as usize];

    let prev: & mut Node = & mut self.data[n.get_prev() as usize];
    prev.set_next(n.get_next());

    let next: & mut Node = & mut self.data[n.get_next() as usize];
    next.set_prev(n.get_prev());

    //other stuff...
}