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

标签 rust iterator

<分区>

我正在尝试实现一个可以无限迭代的结构。把它想象成一个自然数。我有一个限制:它无法实现 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; }
}

我想给我的用户 crate使用 for in 迭代我的结构的能力构造,像这样:

for next_game in game {
  println!("{:?}", next_game);
} 

有可能吗?我怎样才能做到这一点?如何改进我的代码以及我必须如何处理我的结构?

迭代器实现:

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

示例:for 的错误行为

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

现在如果我们运行示例,我们将得到两个 Game具有相同 hash 的结构,而预期的行为是第一个 g会有hash等于 SHA256(game.hash) 和下一个 g的散列将是 SHA256(SHA256(game.hash))。当我调用 .next() 时它工作正常.

最佳答案

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

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

有关更多信息,请参阅相关问题:What is the difference between iter and into_iter? 和文档:The three forms of iteration

要创建迭代器,您应该实现 IntoIterator trait,它将你的结构转换为迭代器或编写将创建迭代器的函数:iter_mut , iter

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> {
        /* ... */
    }
}

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

关于rust - 如何在 Rust 中正确实现 Iterable 结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54379841/

相关文章:

rust - 为什么我的变量生命周期不够长?

swift - swift 中的 iterator.element 是什么?

Rust 类型不匹配但前提是我不使用类型注释

rust - 除非用 `mut` 另行指定,否则为什么在 Rust 中强制执行不可变性?

java - 您如何测试 Iterator/ListIterator 是否有效?

c# - 如何防止 JIT 编译器优化此方法

c++ - 段错误 set_union 与对象:std::set<CardSet>

c++ - 编译错误,提示 'std::basic_string<charT, _Traits, _Alloc>

rust - 如何使用 tokio 的 UdpSocket 处理 1 台服务器中的消息 : N clients setup?

list - 如何在 Rust 中复制一个切片?