对于可变索引锈蚀,是否有替代这种不安全代码的方法

Lyn*_*ock 1 indexing static unsafe rust

我正在制作一个国际象棋游戏,当数组的索引(aVec2超出范围)时,我希望从棋子数组中返回一个可变的空字符,我需要这样做的原因是我的函数用于移动棋子片段需要对索引片段的可变引用,长话短说,我最终需要创建一个NULL_PIECE可以在函数中引用的静态变量,但这可能非常危险,正如您从我的代码中看到的那样

impl Index<IVec2> for Board {
    type Output = Piece;
    fn index(&self, index : IVec2) -> &Self::Output{
        if (index.abs() != index) || (index.max_element() > WIDTH-1) {
            &Piece('\0') // this works
        } else {
            let i : usize = (index.x + WIDTH* index.y).try_into().unwrap();
            &self.pieces[i]
        }
    }
}

impl IndexMut<IVec2> for Board {
    fn index_mut(&mut self, index: IVec2) -> &mut Self::Output{
        if (index.abs() != index) || (index.max_element() > WIDTH-1) {
            // &mut Piece('\0')  // this does not work
            unsafe {&mut NULL_PIECE} // this works but I don't like it
        } else {
            let i : usize = (index.x + WIDTH * index.y).try_into().unwrap();
            &mut self.pieces[i]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果由于我在棋子移动上实现的递归而使其变异为棋子,则很可能会导致错误。

您可以在此处找到 GitHub 链接: https ://github.com/LyndonAlcock/chess_test/tree/main/src

caf*_*e25 5

Index您可以将其写为:

impl Board {
    fn get(&self, index: IVec2) -> Option<&Piece> {
        if (index.abs() != index) || (index.max_element() > WIDTH-1) {
            None
        } else {
            let i = (index.x + WIDTH* index.y).try_into().ok()?;
            Some(&self.pieces[i])
        }
    }
    fn get_mut(&mut self, index: IVec2) -> Option<&mut Piece> {
        if (index.abs() != index) || (index.max_element() > WIDTH-1) {
            None
        } else {
            let i = (index.x + WIDTH * index.y).try_into().ok()?;
            Some(&mut self.pieces[i])
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Indexpanic当索引越界时应该执行。