【发布时间】:2019-06-20 03:33:17
【问题描述】:
我正在尝试实现一个可以无限迭代的结构。把它想象成一个自然数。我有一个限制:它无法实现 Copy 特征,因为该结构包含 String 字段。
我还实现了一个 Iterable 特征及其唯一成员 fn next(&mut self) -> Option<Self::Item>。
目前,我有以下代码来迭代我的结构的前 10 项:
let mut counter = 0;
let mut game:Option<Game> = Game::new(¶m);
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);
}
现在,如果我们运行示例,我们将得到两个具有相同 hash 的 Game 结构,而预期的行为是第一个 g 将具有等于 SHA256(game.hash) 的 hash 和下一个 @ 987654338@ 的哈希值为 SHA256(SHA256(game.hash))。当我拨打.next()时,它可以正常工作。
【问题讨论】:
-
大多数人所做的就是创建一个新结构,例如
GameIter,然后像game.iter()一样将其提供给用户。任何实现Iterator的结构都可以在for ... in ...表达式中使用,如果您想限制迭代次数,只需使用take。 -
如果您提供了
Game结构的实现,这个问题会更加清晰。 -
@AndreyTyukin:
next函数... -
实现
Iterator和IntoIter有什么问题? -
相关:Writing an Iterator?,How to implement Iterator and IntoIterator for a simple struct? 答案基本上在问题标题中......