Многомерный ops::Index

Доброго времени суток!

Интересует как переопределить ops::Index так, чтобы можно было обращаться.

struct Matrix {
    data: Vec<Vec<f64>>,  
}

.....

fn main() {
    let matrix = Matrix::zeros(3, 4);
    let el = matrix[3, 2]; // или matrix[3][2];
}

Пробовал переопределить вот так:

impl Index<(usize, usize)> for Matrix {
    type Output = f64;

    fn index(self, i: (usize, usize)) -> &f64 {
        &self.data[i.0][i.1]
    }
}

Но, это только работает при обращении:

 fn main() {
     let matrix = Matrix::zeros(3, 4);
     let el = matrix[(3, 2)];
 }

Спасибо!

боюсь, такой синтаксис ржавчиной не поддерживается.

matrix[3][2]

а это в базовом виде уже не сложно сделать:

impl Index<usize> for Matrix {
    type Output = &[f64];

    fn index(self, i: usize) -> &[f64] {
        &self.data[i]
    }
}

^ что-то в таком духе.

Тогда первый оператор индексирования вернет нужную строку\столбец, а второй уже вытащить оттуда нужный элемент.

Хотя по мне вариант matrix[(3, 2)] самый “ржавый” - он немного длинее, но так проще скрыть всякие детали реализации и вспомогательного кода меньше.

Спасибо за ответ. Я немного не понимаю, что он вцепился в меня со своим временем жизни.

Ещё вопрос к Вам. Читал документацю и обнаружил вот такой пример: https://doc.rust-lang.org/std/ops/trait.Index.html. Почему в Вашем примере тип Output и возвращаемый тип -> одинаковы? Я понимаю логически, что можно сделать -> Self::Output и это должно работать, но в примере документации типы разные.

Правильно прицепился, я набросок написал.

Полную реализацию можно, допустим, в cgmath подсмотреть: https://docs.rs/cgmath/0.15.0/src/cgmath/matrix.rs.html#1112-1120

Про возвращаемый тип: опять же, вышенаписаный мной код только набросочный, он не соберется как есть.

Index действительно требует возвращения именно -> &Self::Output, т.е. ссылки на то что указано в Output.