Lodin
Lodin

Reputation: 2068

Is there a way to implement a trait method with a different signature?

I am creating simple matrix implementation in Rust. I need to iterate over the matrix, getting the coordinates in addition to the value:

for (i, j, elem) in matrix.iter().enumerate() {
    ...
}

As far as I can see, Iterator::enumerate is pre-defined and I cannot override it with a custom implementation which is able to return (usize, usize, &T). Is there a way to implement a custom enumerate() method?

Upvotes: 2

Views: 1343

Answers (2)

Shepmaster
Shepmaster

Reputation: 432089

It is correct that you cannot change the signature of Iterator::enumerate; doing so wouldn't implement the trait as any other consumer would expect. However, you can create an enumerate method directly on your Matrix that does what you want:

struct Matrix {
    value: u8,
    size: usize,
}

impl Matrix {
    fn enumerate(&self) -> MatrixEnumerate {
        MatrixEnumerate {
            matrix: self,
            pos: 0,
        }
    }
}

struct MatrixEnumerate<'a> {
    matrix: &'a Matrix,
    pos: usize,
}

impl<'a> Iterator for MatrixEnumerate<'a> {
    type Item = (usize, usize, &'a u8);

    fn next(&mut self) -> Option<(usize, usize, &'a u8)> {
        if self.pos < self.matrix.size {
            let v = Some((self.pos, self.pos, &self.matrix.value));
            self.pos += 1;
            v
        } else {
            None
        }
    }
}

fn main() {
    let m = Matrix {
        value: 42,
        size: 10,
    };
    for (x, y, v) in m.enumerate() {
        println!("{}, {}: {}", x, y, v);
    }
}

Here, I'm skipping the complexity of the matrix and just advancing down the diagonal. Your real implementation has to deal with row-major or column-major iteration and properly wrapping at the end of the row/column.

Upvotes: 6

FlyingFoX
FlyingFoX

Reputation: 3509

I think the best way to deal with your problem is to create a new trait that defines a function like enumerate2D() that has the kind of signature you want.

Upvotes: 1

Related Questions