编者注:此代码示例来自1.0之前的Rust版本,并且不是有效的Rust 1.0代码.由于更改了
for
循环的实现方式,此代码的更新版本不再产生错误.
我正在Rust中编写一个Vector结构.
pub struct Vector {
pub x: f32,
pub y: f32,
pub z: f32,
curr: uint
}
Run Code Online (Sandbox Code Playgroud)
我想为它编写一个简单的迭代器,以便我可以迭代向量的元素.它偶尔会有用,而且我对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
}
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望能够像以下一样使用它:
let u = Vector::new(0.0f32, 0.0f32, 0.0f32);
for element in u {
///
}
Run Code Online (Sandbox Code Playgroud)
但是,我得到以下编译器错误:
error: cannot borrow immutable local variable `u` as mutable
Run Code Online (Sandbox Code Playgroud)
所以我很难过.经过几个小时的谷歌搜索,我无法想出任何东西.我觉得我错过了一些巨大的东西.
Vla*_*eev 15
你确定你真的希望Vector
自己成为一个迭代器吗?通常,结构和迭代器是分开的.考虑这样的事情:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
因为Vector
它非常简单,它可以派生Copy
,并且它的迭代器可以通过值来获取它:
#[derive(Copy, Clone)]
pub struct Vector {
pub x: f32,
pub y: f32,
pub z: f32,
}
pub struct VectorIter {
vector: Vector,
cur: usize,
}
impl Iterator for VectorIter {
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);
}
}
Run Code Online (Sandbox Code Playgroud)
除非您Vector
包含除坐标之外的其他内容,否则此变体可能更好.这个变体更灵活,因为它没有将迭代器与迭代器绑定,但另一方面,正是由于同样的原因,它可能是不可取的(Copy
你可以改变原始值,迭代器不会反映它;没有Copy
和有参考,你将无法改变原始值.您希望大量使用的语义取决于您的用例.