Consider the classic example of a const-generic datastructure: a square matrix.
struct Matrix<T, const N: usize> {
inner: [[T; N]; N]
}
I'd like to return a structure whose const parameter is dynamically defined:
fn read_matrix() -> ??? {
let n: usize = todo!() // the N is decided dynamically
let r: Box<Matrix<u8, {n}>> = todo!();
r
}
but:
- Rust will complain that
n
is not a constant - I cannot write an appropriate return type :
fn read_matrix<const N: usize>() -> Matrix<u8, N>
is not adequate, as it lets the caller choose the N, where I want N to be determined in runtime.
I can work around the second limitation by defining a trait:
trait DynamiMatrix {
fn size(&self) -> usize;
fn some_method(&self);
...
}
impl<T, const N: usize> DynamicMatrix for Matrix<T,N> {
fn size(&self) -> usize { N };
fn some_method(&self){ ... }
...
}
But, for construction, the best I can try is:
fn read_array_pair() -> Box<dyn DynamicMatrix> {
let n: usize = todo!();
let m = Box::new(Matrix { inner: [[0; n]; n] });
todo!(); // fill up m
m
}
and Rust will still complain that n is not constant.
Is there any way to achieve this? If possible without falling back to nested Vec
s, because i'd like my square invariant to be enforced?