Let's say I have a Matrix
trait and two concrete implementations—a RowMajorMatrix
implementation and ColumnMajorMatrix
implementation. Each struct stores the dimensions and a Vec
of elements. In this design, implementing matrix transpose on an owned matrix is pretty straightforward, simply move the elements from the row major struct into a new column major struct and vice versa. The code looks like this:
trait Matrix<E> {
type Transpose: Matrix<E>;
fn height(&self) -> usize;
fn width(&self) -> usize;
fn t(self) -> Self::Transpose;
}
struct RowMajorMatrix<E> {
n: usize,
m: usize,
elements: Vec<E>
}
impl<E> Matrix<E> for RowMajorMatrix<E> {
type Transpose = ColumnMajorMatrix<E>;
fn height(&self) -> usize { self.n }
fn width(&self) -> usize { self.m }
fn t(self) -> Self::Transpose {
ColumnMajorMatrix { n: self.m, m: self.n, elements: self.elements }
}
}
struct ColumnMajorMatrix<E> {
n: usize,
m: usize,
elements: Vec<E>
}
impl<E> Matrix<E> for ColumnMajorMatrix<E> {
type Transpose = RowMajorMatrix<E>;
fn height(&self) -> usize { self.n }
fn width(&self) -> usize { self.m }
fn t(self) -> Self::Transpose {
RowMajorMatrix { n: self.m, m: self.n, elements: self.elements }
}
}
fn main() {
let rowmat = RowMajorMatrix { n: 2, m: 3, elements: vec![1, 2, 3, 4, 5, 6] };
let colmat = rowmat.t();
}
There should also be version of transpose for a borrowed matrix. Let's call this method t_borrow
, and I'll figure out how to do the overloading later. If the receiver is &self
, then I would like transpose to return &Self::Transpose
, which doesn't work for reasons that make sense to me, but it is not clear how to accomplish what I want.
trait Matrix<E> {
...
fn t_borrow(&self) -> &Self::Transpose;
}
impl<E> Matrix<E> for RowMajorMatrix<E> {
...
// Doesn't work obviously, but hopefully shows the goal
fn t_borrow(&self) -> &Self::Transpose {
&ColumnMajorMatrix { n: self.m, m: self.n, elements: self.elements }
}
}
The returned value needs to have a shorter lifetime than &self
and needs to never actually free its elements, but I don't know how to say that in Rust.