Based on your question it looks like you're trying to use a matrix object.
There are multiple ways to do that in rust:
Compile-Time matrices:
Using const generics it's now very easy to define the matrix object with an array of arrays:
pub struct Matrix<T, const ROWS: usize, const COLS: usize> {
data: [[T; COLS]; ROWS],
}
impl<T, const ROWS: usize, const COLS: usize> Matrix<T, ROWS, COLS> {
pub fn new(data: [[T; COLS]; ROWS]) -> Self {
Self { data }
}
}
impl<T, const ROWS: usize, const COLS: usize> Index<(usize, usize)> for Matrix<T, ROWS, COLS> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.data[index.0][index.1]
}
}
Here, the amount of rows and columns are hard-coded into the data-type.
So to resize you need to a create a new object and all types must be known (defined) at compile time.
Dynamic matrices:
If you want run-time (dynamic) sizing, the simplest solution is to use a vector of vectors:
pub struct Matrix<T> {
data: Vec<Vec<T>>,
}
impl<T> Matrix<T> {
pub fn new(data: Vec<Vec<T>>) -> Self {
Self { data }
}
}
impl<T> Index<(usize, usize)> for Matrix<T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.data[index.0][index.1]
}
}
Note that since vectors are pointers to memory on the heap, the items won't usually be contiguous in memory.
You can build contiguous dynamic matrices by using a single vector and indices to map to chunks of it:
pub struct Matrix<T> {
rows: usize,
cols: usize,
data: Vec<T>,
}
impl<T> Matrix<T> {
pub fn new(rows: usize, cols: usize, data: Vec<T>) -> Self {
assert_eq!(rows * cols, data.len());
Self { rows, cols, data }
}
}
impl<T> Index<(usize, usize)> for Matrix<T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.data[index.0 * self.cols + index.1]
}
}
Vec<Vec<i32>>is probably what you want. Its an array of arrays, rather than a 2D array. Alternatively you might want to look on crates.io.