Iterator 编写迭代器
编者注:此代码示例来自Rust 1.0之前的版本,不是有效的Rust 1.0代码。由于Iterator 编写迭代器,iterator,rust,Iterator,Rust,编者注:此代码示例来自Rust 1.0之前的版本,不是有效的Rust 1.0代码。由于for循环的实现方式发生更改,此代码的更新版本不再产生错误 我正在用Rust写一个向量结构 pub struct Vector { pub x: f32, pub y: f32, pub z: f32, curr: uint } 我想为它写一个简单的迭代器,这样我可以迭代向量的元素。它偶尔有用,而且我对Rust中的迭代器几乎一无所知 这是我目前得到的 impl Iterato
for
循环的实现方式发生更改,此代码的更新版本不再产生错误
我正在用Rust写一个向量结构
pub struct Vector {
pub x: f32,
pub y: f32,
pub z: f32,
curr: uint
}
我想为它写一个简单的迭代器,这样我可以迭代向量的元素。它偶尔有用,而且我对Rust中的迭代器几乎一无所知
这是我目前得到的
impl Iterator<f32> for Vector {
fn next(&mut self) -> Option<f32> {
let new_next : Option<f32> = match self.curr {
0 => Some(self.x),
1 => Some(self.y),
2 => Some(self.z),
_ => None
};
let new_curr = (self.curr + 1) % 4;
mem::replace(&mut self.curr, new_curr);
new_next
}
}
但是,我得到以下编译器错误:
error: cannot borrow immutable local variable `u` as mutable
所以我被难住了。在谷歌搜索了几个小时后,我什么都想不出来。我觉得我错过了一些重大的事情 您确定要将
向量本身作为迭代器吗?通常结构和迭代器是分开的。考虑这样的事情:
pub struct Vector {
pub x: f32,
pub y: f32,
pub z: f32,
}
pub struct VectorIter<'a> {
vector: &'a Vector,
cur: usize,
}
impl<'a> Iterator for VectorIter<'a> {
type Item = f32;
fn next(&mut self) -> Option<f32> {
let r = match self.cur {
0 => self.vector.x,
1 => self.vector.y,
2 => self.vector.z,
_ => return None,
};
self.cur += 1;
Some(r)
}
}
impl Vector {
fn iter(&self) -> VectorIter {
VectorIter {
vector: self,
cur: 0,
}
}
}
fn main() {
let v = Vector { x: 1.0, y: 2.0, z: 3.0 };
for c in v.iter() {
println!("{}", c);
}
}
除非向量
包含坐标以外的内容,否则此变量可能更好。这种变体更灵活,因为它不会将迭代器与iterable绑定在一起,但另一方面,正是由于同样的原因,它可能不受欢迎(使用Copy
可以更改原始值,迭代器不会反映它;没有Copy
和引用,您将无法更改原始值)。您希望使用的语义在很大程度上取决于您的用例
编者按:由于for
循环的工作方式发生了变化,从Rust 1.0开始,这个答案不再有用
弗拉基米尔·马特维耶夫的回答是正确的,并且解释了你应该做什么。我想补充一点,解释一下你的错误
错误:无法将不可变的局部变量u
借用为可变的
当您在某个对象上进行迭代时,您需要对跟踪您所在位置的对象进行变异。在您的代码中,这是通过以下方式完成的:
mem::replace(&mut self.curr, new_curr);
Rust知道你想变异什么,因为next
的方法签名表明:
fn next(&mut self) -> Option<f32>
如果您将代码更改为
let mut u = Vector::new(0.0f32, 0.0f32, 0.0f32);
我希望您的代码能按原样工作。尽管如此,单独的迭代器可能是正确的选择。但是,您对代码的了解将比我们多!这更有意义。非常感谢!我认为当您实现迭代器时,您必须分配类型别名type Item=f32;
。我无法像我一样编译此代码请更新此问题或在标题中将其标记为已过时;迭代器现在使用关联类型,此问题不再反映在问题或答案中实现它们的正确方式。
fn next(&mut self) -> Option<f32>
let u = Vector::new(0.0f32, 0.0f32, 0.0f32);
let mut u = Vector::new(0.0f32, 0.0f32, 0.0f32);