如何在Rust中正确实现Iterable结构?

Vla*_*yev 6 iterator rust

我正在尝试实现可以​​无限迭代的结构。认为它是自然数。我有一个局限性:它不能实现Copy特征,因为结构包含一个String字段。

我还实现了一个Iterable特征及其唯一成员fn next(&mut self) -> Option<Self::Item>

当前,我有以下代码可以迭代结构的前10个项目:

let mut counter = 0;
let mut game:Option<Game> = Game::new(&param);
loop {
    println!("{:?}", game); 

    game = g.next();
    counter = counter + 1;
    if counter > 10 { break; }
}
Run Code Online (Sandbox Code Playgroud)

我想让用户crate能够使用for in构造对我的结构进行迭代,如下所示:

for next_game in game {
  println!("{:?}", next_game);
} 
Run Code Online (Sandbox Code Playgroud)

有可能吗?我该如何实现?如何使我的代码更好,以及与我的结构有什么关系?

迭代器实现:

pub struct Game {
    /// The game hash
    pub hash: Vec<u8>
}

impl Iterator for Game {
    type Item = Game;

    fn next(&mut self) -> Option<Self::Item> {
        let mut hasher = Sha256::new();
        hasher.input(&hex::encode(&self.hash)); // we need to convert the hash into string first
        let result = hasher.result().to_vec();

        Some(Game {
            hash: result
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

示例:行为破坏 for

let mut game:Game = Game::new(&s).unwrap();
for g in game.take(2) {
    println!("{}", g);
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们运行示例,我们将获得两个Game具有相同结构的结构hash,而预期的行为是第一个结构ghash等于SHA256(game.hash),下一个g的哈希将是SHA256(SHA256(game.hash))。当我打电话时它可以正常工作.next()

Inl*_*ine 5

在 Rust 中迭代器实际上可以分为 2 类。拥有该结构的迭代器,因此可以使用.into_iter()which来创建self

以及迭代结构而不消耗它的迭代器。通常可以使用以下方法创建它们:.iter,.iter_mut()

有关更多信息,请参阅相关问题:iter 和 into_iter 有什么区别? 和文档:迭代的三种形式

要创建迭代器你应该实现两种IntoIterator特质,这将改变你的结构到迭代器或写入功能,这将创造迭代器iter_mutiter

pub fn iter_mut(&mut self) -> IterMut<T>

pub fn iter(&self) -> Iter<T>

所以按照惯例,你需要 2 个新类型IterMutIter

impl Iterator for Iter {
    type Item = /* ... */;
    fn next(&mut self) -> Option<Self::Item> {
        /* ... */
    }
}

impl Iterator for IterMut {
    type Item = &mut /* ... */;
    fn next(&mut self) -> Option<Self::Item> {
        /* ... */
    }
}
Run Code Online (Sandbox Code Playgroud)

它们通常包含对父结构的引用。例如对于链表,它可以是当前节点(每次迭代都会更新)。对于类似数组的结构,它可以是对父项的索引和引用,因此每次使用索引运算符等访问元素和元素时,索引都会增加。