有没有办法实现具有不同签名的特征方法?

时间:2015-04-06 16:36:40

标签: rust traits

我在Rust中创建简单的矩阵实现。我需要迭代矩阵,除了值之外还得到坐标:

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

据我所知,Iterator::enumerate是预先定义的,我无法使用能够返回(usize, usize, &T)的自定义实现覆盖它。有没有办法实现自定义enumerate()方法?

2 个答案:

答案 0 :(得分:5)

您无法更改Iterator::enumerate的签名是正确的;这样做不会像任何其他消费者所期望的那样实现这种特性。但是,您可以直接在enumerate创建一个Matrix方法来执行您想要的操作:

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);
    }
}

在这里,我正在跳过矩阵的复杂性,只是沿着对角线前进。您真正的实现必须处理行主要或列主要迭代并在行/列的末尾正确包装。

答案 1 :(得分:1)

我认为处理问题的最佳方法是创建一个新的特征,定义一个像enumerate2D()这样的函数,它具有你想要的签名类型。