Rust 如何实现装箱值的迭代器?

Rust 如何实现装箱值的迭代器?,rust,Rust,我有一个结构,它通过trait迭代器中的方法next给出数字: struct Numbers{ number: usize, count: usize } impl Iterator for Numbers { type Item = usize; fn next(&mut self) -> Option<Self::Item> { if self.count > 0 { self.cou

我有一个结构,它通过trait
迭代器中的方法
next
给出数字:

struct Numbers{
    number: usize,
    count: usize
}

impl Iterator for Numbers {
    type Item = usize;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count > 0 {
            self.count -= 1;
            return Some(self.number);
        }

        return None;
    }
}

fn main(){
    let numbers = Numbers{
        number: 777,
        count: 10
    };

    for n in numbers {
        println!{"{:?}", n};
    }
}
./numbers.rs:12:25:12:29错误:无法移出借用的内容

./number.rs:12返回一些(自我编号)


如何正确地为装箱值实现迭代器?

这可以归结为Rust的所有权模型以及复制和移动语义之间的区别
Box
具有移动语义,没有实现
Copy
,因此
返回一些(self.number)
将移动
self.number
,获得它的所有权;但这是不允许的,因为它将需要消费
self
,这仅由可变引用获取

您有几个选择(我写的“具有移动语义的对象”,我的意思是在这个特定的例子中
self.number
):

  • 不要返回具有移动语义的对象,而是返回具有复制语义引用的其他对象,例如引用而不是装箱值(返回引用将要求迭代器对象与被迭代的对象不同,这样您就可以在
    项中写入生存期;因此它不适用于您的特定用例)或未绑定的数字

  • 基于具有移动语义的对象构造要返回的新值:

    impl数字迭代器{
    类型项=框;
    fn下一步(&mut self)->选项{
    如果self.count>0{
    self.count-=1;
    一些(框::新(自我编号))
    }否则{
    没有一个
    }
    }
    }
    
  • 使用移动语义克隆对象(实际上,这是第二个选项的简化形式):

    impl数字迭代器{
    类型项=框;
    fn下一步(&mut self)->选项{
    如果self.count>0{
    self.count-=1;
    一些(self.number.clone())
    }否则{
    没有一个
    }
    }
    }
    
  • 构造一个新值以替换具有移动语义的对象:

    使用std::mem;
    数字的impl迭代器{
    类型项=框;
    fn下一步(&mut self)->选项{
    如果self.count>0{
    self.count-=1;
    让number=mem::replace(&mut self.number,Box::new(0));
    //self.number现在包含0
    一些(数字)
    }否则{
    没有一个
    }
    }
    }
    
  • struct Numbers{
        number: Box<usize>,
        count: usize
    }
    
    impl Iterator for Numbers {
        type Item = Box<usize>;
    
        fn next(&mut self) -> Option<Self::Item> {
            if self.count > 0 {
                self.count -= 1;
                return Some(self.number);
            }
    
            return None;
        }
    }
    
    fn main(){
        let numbers = Numbers{
            number: Box::new(777),
            count: 10
        };
    
        for n in numbers {
            println!{"{:?}", n};
        }
    }