Looking at the signature of Index and IndexMut, we note that the signature enforces that the returned type be &'a [mut] Return
where only Result
is customizable.
Given such a signature:
pub trait IndexMut<Index, Result> {
fn index_mut(&'a mut self, index: &Index) -> &'a mut Result;
}
It seems infeasible to actually return proxies (and thus, to implement views).
For example, a silly example:
struct Matrix<T> {
nb_lines: uint,
nb_columns: uint,
data: Vec<T>,
}
impl Matrix<T> {
fn get<'a>(&'a self, line: uint, col: uint) -> &'a {
self.data.get(line * self.nb_columns + col)
}
}
struct LazilyTransposedMatrix<'a, T> {
base: &'a Matrix<T>,
}
impl LazilyTransposedMatrix<'a, T> {
fn get(&self, line: uint, col: uint) -> &'a T {
self.base.get(col, line)
}
}
Now, if Iâd like to implement []
on my lazily transposed matrix, I cannot just return a reference, what I need is a proxy:
struct LazilyTransposedRow<'a, T> {
base: &'a Matrix<T>,
row_index: uint,
}
impl <'a, T> Index<uint, LazilyTransposedRow<'a, T>> for LazilyTransposedMatrix<T> {
fn index(&'a self, index: uint) -> LazilyTransposedRow<'a, T> {
LazilyTransposedRow { base: self, row_index: index }
}
}
impl <'a, T> Index<uint, &'a T> for LazilyTransposedRow<'a, T> {
fn index(&'a self, index: uint) -> &'a T {
self.base.get(row_index, index)
}
}
This looks (to me) like a typical example of views, however this will fail to compile because the signature of index
will not match that of the trait. I looked for, but could not find, any rationalization for specifying the trait as it is, and thus was wondering whether I was missing something obvious or had just stumbled on an oversight.
Is there any reason not to make the trait more general ?
Note: this seems opposed to the design of iterators which were specifically made so that returning a view is possible.