我在Rust中创建简单的矩阵实现。我需要迭代矩阵,除了值之外还得到坐标:
for (i, j, elem) in matrix.iter().enumerate() {
...
}
据我所知,Iterator::enumerate
是预先定义的,我无法使用能够返回(usize, usize, &T)
的自定义实现覆盖它。有没有办法实现自定义enumerate()
方法?
答案 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()这样的函数,它具有你想要的签名类型。