Rust 当某些值被忽略时,如何避免迭代器实现中不必要的昂贵操作?

Rust 当某些值被忽略时,如何避免迭代器实现中不必要的昂贵操作?,rust,iterator,traits,lazy-evaluation,iterator-traits,Rust,Iterator,Traits,Lazy Evaluation,Iterator Traits,我有一个迭代器实现,如下所示: struct MyType { // stuff } struct Snapshot { // stuff } impl MyType { pub fn iter(&mut self) -> MyIterator { MyIterator { foo: self } } } struct MyIterator<'a> { foo: &am

我有一个
迭代器
实现,如下所示:

struct MyType {
    // stuff
}

struct Snapshot {
    // stuff
}

impl MyType {
    pub fn iter(&mut self) -> MyIterator {
        MyIterator {
            foo: self
        }
    }
}

struct MyIterator<'a> {
    foo: &'a mut MyType
}

impl<'a> Iterator for MyIterator<'a> {
    type Item = Snapshot;

    fn next(&mut self) -> Option<Self::Item> {
        if self.cheap_condition() {
           self.cheap_mutation();  // Inexpensive
           let s: Snapshot = self.snapshot();  // Expensive copying
           Some(s)
        } else {
           None
        }
    }
}
struct MyType{
//东西
}
结构快照{
//东西
}
impl MyType{
pub fn iter(&mut self)->MyIterator{
我的迭代器{
福:自我
}
}
}
结构MyIterator{
类型项=快照;
fn下一步(&mut self)->选项{
如果self.cheap_条件(){
self.cheap_mutation();//便宜
设s:Snapshot=self.Snapshot();//昂贵的复制
部分
}否则{
没有一个
}
}
}
如果我想使用生成的
快照
的每个实例,这很好,但是如果我想使用
迭代器::step_by
迭代器::last
之类的东西,我不关心中间的
快照
,那么生成这些未使用的值所产生的成本是一个巨大的性能损失

我可以覆盖
迭代器的每一个方法,这样昂贵的操作只在必要时发生,但我觉得必须有一种更简单、更惯用的方法来完成,或者,如果未再次调用
迭代器::next
,则可以通过中间类型为
惰性地生成与迭代相对应的
快照


我不想返回对
MyType
的引用,因为我希望生成的
Snapshot
s具有独立的生存时间,例如,允许
Iterator::collect()
的结果比
MyType
的实例寿命长,您不必覆盖每个
迭代器
方法。唯一相关的是第n个
最后一个
计数
步进
,和
跳过
。所有其他方法都需要以某种方式检查
Self::Item
,因此无法避免为这些方法生成
Snapshot
s。幸运的是,
step\u by
skip
在内部使用
nth
,因此我们只剩下
nth
count
last
,我们必须覆盖:

使用core::marker::PhantomData;
结构快照;
结构MyType,
}
恳求{
fn廉价_条件(自身)->bool{
待办事项!()
}
fn廉价突变(&mut-self){
待办事项!()
}
fn快照(&self)->快照{
快照
}
}
恳求{
类型项=快照;
fn下一步(&mut self)->选项{
如果self.cheap_条件(){
self.cheap_mutation();//便宜
有些(self.snapshot())//价格昂贵
}否则{
没有一个
}
}
//还包括方法的跳过和步骤
fn第n个(&mut self,n:usize)->选项{
对于0..n中的uu{
如果self.cheap_条件(){
self.cheap_突变();
}否则{
不返回任何值;
}
}
self.next()
}
fn计数(多个自身)->使用
哪里
自我:大小,
{
让mut计数:usize=0;
而self.cheap_条件(){
self.cheap_突变();
计数+=1;
}
计数
}
fn最后一个(多个自)->选项
哪里
自我:大小,
{
而self.cheap_条件(){
self.cheap_突变();
if!self.cheap_条件(){
返回一些(self.snapshot());
}
}
没有一个
}
}


如果您想通过检查
MyTypeI的谓词使其他
Iterator
方法(如
filter
)变得懒惰,我可以覆盖Iterator的每个方法,这样昂贵的操作只在必要时发生-我相信这是正确的解决方案。如果是,那么我想没有其他选择,我想我可以添加某种函数来避免重复相同的代码,但我想看看是否有人有更好的想法。谢谢你的编辑。谢谢你的回答!我不确定
step_by
等的内部实现,因此感谢您的澄清。我想这是正确的答案,所以我会将其标记为正确答案。另外相关的可能是
iter\u advance\u by
功能,尽管它目前(尚未)稳定。
last
的实现是错误的:如果迭代器为空,它将到达无法访问的
!()
声明@谢谢你的评论,我更新了我的答案。