编写迭代器 [英] Writing an iterator
问题描述
编者注:此代码示例摘自1.0之前的Rust版本,并且不是有效的Rust 1.0代码.由于更改了
for
循环的实现方式,因此该代码的更新版本不再产生错误.
Editor's note: This code example is from a version of Rust prior to 1.0 and is not valid Rust 1.0 code. Updated versions of this code no longer produce an error due to changes how
for
loops are implemented.
我正在用Rust写一个Vector结构.
I'm writing a Vector struct in Rust.
pub struct Vector {
pub x: f32,
pub y: f32,
pub z: f32,
curr: uint
}
我想为其编写一个简单的迭代器,以便可以迭代向量的元素.它偶尔有用,而且我几乎不了解Rust中的迭代器.
And I'd like to write a simple iterator for it, so that I can iterate over the elements of the vector. It's occasionally useful, plus I know next to nothing about iterators in Rust.
这就是我现在所拥有的.
Here's what I've got at the moment.
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
}
}
现在理想情况下,我希望能够像这样使用它:
Now ideally I'd like to be able to use this like:
let u = Vector::new(0.0f32, 0.0f32, 0.0f32);
for element in u {
///
}
但是,出现以下编译器错误:
However, I get the following compiler error:
error: cannot borrow immutable local variable `u` as mutable
所以我很困惑.经过两个小时的谷歌搜索,我什么都没想出来.我觉得我想念一些巨大的东西.
So I'm stumped. After a couple hours of Googling, I couldn't come up with anything. I feel like I'm missing something huge.
推荐答案
您确定要真正将Vector
本身用作迭代器吗?通常,结构和迭代器是分开的.考虑这样的事情:
Are you sure you really want the Vector
itself to be an iterator? Usually structures and iterators into them are separate. Consider something like this:
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);
}
}
因为Vector
非常简单,它可以派生Copy
,并且其迭代器可以按值获取它:
Because Vector
is very simple, it can derive Copy
, and its iterator can take it by value:
#[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);
}
}
除非您的Vector
包含坐标以外的其他内容,否则此变体可能更好.此变体更加灵活,因为它不会将迭代器与可迭代器绑定在一起,但是,另一方面,正是由于相同的原因,它可能是不可取的(使用Copy
,您可以更改原始值,而迭代器不会反映它;没有Copy
和引用,您将根本无法更改原始值).您希望大量使用的语义取决于您的用例.
This variant is probably better unless your Vector
contains something other than coordinates. This variant is more flexible because it does not tie the iterator with the iterable, but on the other hand, exactly because of the same reason it may be undesirable (with Copy
you can change the original value, and the iterator won't reflect it; without Copy
and with references you won't be able to change the original value at all). The semantics you would want to use heavily depends on your use cases.
这篇关于编写迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!