首页 > 解决方案 > Rust 中的耦合数组

问题描述

我正在尝试将 2 个数组耦合到一个“父数组”。我想要一个像这样的主数组,例如:

let mut board: [[u8; 4]; 4] = [[1, 6, 5, 2],
                               [4, 8, 9, 3],
                               [9, 2, 2, 5], 
                               [3, 7, 6, 7]];

还有 2 个其他数组,一个用于列,一个用于 2*2 正方形。当我更改主数组中的某些内容时,其他两个数组应该更新。

在示例中,另外两个数组如下所示:

columns
[[1, 4, 9, 3],
 [6, 8, 2, 7],
 [5, 9, 2, 6],
 [2, 3, 5, 7]]

2*2 squares
[[1, 6, 4, 8],
 [5, 2, 9, 3],
 [9, 2, 3, 7],
 [2, 5, 6, 7]]

现在,如果我说 board[0][0] = 5;列数组现在应该如下所示:

[[5, 4, 9, 3],
 [6, 8, 2, 7],
 [5, 9, 2, 6],
 [2, 3, 5, 7]]

有没有办法在 Rust 中做这样的事情?

标签: arraysrust

解决方案


具有相关特征实现的新类型模式可能是一个解决方案。这些应该将索引映射到基本数组,例如,对于您的第一种情况,可以通过std::ops::Index游乐场)完成不可变访问:

struct Board([[u8; 4]; 4]);

impl Board {
    fn column(&self) -> ColumnBoard {
        ColumnBoard(self)
    }
}

struct ColumnBoard<'a>(&'a Board);

impl<'a> std::ops::Index<(usize, usize)> for ColumnBoard<'a> {
    type Output = u8;
    
    fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
        &(self.0).0[y][x]
    }
}

fn main() {
    let board = Board([[1, 6, 5, 2],
                       [4, 8, 9, 3],
                       [9, 2, 2, 5], 
                       [3, 7, 6, 7]]);
                       
    let column = board.column();
    assert_eq!(column[(0, 2)], 9);
}

同样,您可以为第二种情况做。如果您想进行两次索引操作,您可能会更改Output为临时结构,该结构也实现了std::ops::Index. 对于可变性,您需要另外实现std::ops::IndexMut游乐场):

impl<'a> std::ops::IndexMut<(usize, usize)> for ColumnBoard<'a> {
    fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
        &mut (self.0).0[y][x]
    }
}

// besides structures must explicitly declare mutability:

impl Board {
    fn column(&mut self) -> ColumnBoard {
        ColumnBoard(self)
    }
}

struct ColumnBoard<'a>(&'a mut Board);

推荐阅读