简体   繁体   English

我如何编写一个通用迭代器,该迭代器在不使用克隆的情况下保持状态并返回值?

[英]How do I write a generic iterator that keeps a state and returns a value without using clone?

I tried to write a generic iterator, but I do not see how to return value without using clone . 我试图编写一个通用的迭代器,但是如果不使用clone ,我看不到如何返回值。 Is there any way to create a variable within the next function and return a reference? 有什么方法可以next函数中创建变量并返回引用? If I replace T with u32 , then I can just return Some(self.count) , but using generics, it is not possible. 如果我更换Tu32 ,然后我就可以返回Some(self.count)但是使用泛型,这是不可能的。

use num_traits::Num;
use std::clone::Clone;

struct Counter<T>
where
    T: Num + Clone,
{
    count: T,
}

impl<T> Counter<T>
where
    T: Num + Clone,
{
    fn new() -> Counter<T> {
        Counter { count: T::zero() }
    }
}

impl<T> Iterator for Counter<T>
where
    T: Num + Clone,
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.count = self.count.clone() + T::one();
        Some(self.count.clone())
    }
}

fn main() {
    let mut number: Counter<u32> = Counter::new();

    match number.next() {
        Some(x) => println!("Number {}", x),
        None => println!("Invalid"),
    }
}

On the one hand... no, you cannot make the iterator return a reference to the counter's value. 一方面...不,您不能使迭代器返回对计数器值的引用。 The Iterator::next() method returns a value which has no lifetime connection with the receiver value &mut self , so we cannot control the lifetime of the reference that would be returned there. Iterator::next()方法返回的值与接收器值&mut self没有生命周期的关系,因此我们无法控制在那里返回的引用的生命周期。 This would be required because we cannot modify the value while it's borrowed by that reference. 这是必需的,因为当该引用借用该值时我们无法对其进行修改。 This concern is better explained in another question . 在另一个问题中可以更好地解释这种担忧。

On the other hand , the real concern emerges here: 另一方面 ,真正的担忧出现在这里:

If I replace T with u32 , then I can just return Some(self.count) , but using generics, it is not possible. 如果我更换Tu32 ,然后我就可以返回Some(self.count)但是使用泛型,这是不可能的。

This is only the case because u32 implements Copy , which means that it is copied around whenever it is necessary. 这是唯一的情况,因为u32实现了Copy ,这意味着它在需要时u32被复制。 Types implementing Copy also implement Clone , which would do just about the same thing as a copy, which would have happened in the non-generic context. 实现Copy类型还实现了Clone ,它将与非复制上下文中发生的复制做几乎相同的事情。

As such, the cloning operations that you have in this are reasonable, since you want to return the value of the counter while still owning its own state. 因此,您在其中进行的克隆操作是合理的,因为您希望在仍拥有其自身状态的同时返回计数器的值。 When the T of that counter is a primitive integer such as u32 , the clone is as cheap as a copy of that integer. 当该计数器的T是原始整数(例如u32 ,副本的价格与该整数的副本一样便宜。

Other than that, you can add a constraint for T on AddAssign<T> , so that you can use the += operator to increment the internal state. 除此之外,您可以在AddAssign<T>上为T添加一个约束,以便可以使用+=运算符来递增内部状态。

impl<T> Iterator for Counter<T> where T: Num + Clone + AddAssign<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.count += T::one();
        Some(self.count.clone())
    }
}

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM