编写迭代器[重复]

2024-04-05

编者注:此代码示例来自 Rust 1.0 之前的版本,不是有效的 Rust 1.0 代码。此代码的更新版本不再因更改方式而产生错误for循环被实现。

我正在用 Rust 编写一个 Vector 结构。

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

现在理想情况下我希望能够像这样使用它:

let u = Vector::new(0.0f32, 0.0f32, 0.0f32);
for element in u {
    ///
}

但是,我收到以下编译器错误:

 error: cannot borrow immutable local variable `u` as mutable

所以我很困惑。经过几个小时的谷歌搜索后,我什么也想不出来。我觉得我错过了一些巨大的东西。


你确定你真的想要Vector itself成为迭代器?通常结构和其中的迭代器是分开的。考虑这样的事情:

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

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

这个变体可能更好,除非你Vector包含坐标以外的内容。这种变体更灵活,因为它不会将迭代器与可迭代对象联系起来,但另一方面,正是由于同样的原因,它可能是不可取的(与Copy你可以改变原始值,迭代器不会反映它;没有Copy并且通过引用,您将根本无法更改原始值)。您想要使用的语义在很大程度上取决于您的用例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写迭代器[重复] 的相关文章

随机推荐