代码之家  ›  专栏  ›  技术社区  ›  HamoriZ

如何更改迭代器状态

  •  0
  • HamoriZ  · 技术社区  · 7 年前

    clone . 有没有办法在 next 函数并返回引用?如果我更换 T 具有 u32 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"),
        }
    }
    
    0 回复  |  直到 7 年前
        1
  •  4
  •   Shepmaster Tim Diekmann    7 年前

    一方面。。。不,不能使迭代器返回对计数器值的引用。这个 Iterator::next() 方法返回与接收器值没有生存期连接的值 &mut self ,因此我们无法控制将在那里返回的引用的生存期。这是必需的,因为我们不能在引用借用值时修改它。这个问题在另一个例子中得到了更好的解释 question .

    ,真正的问题出现在这里:

    如果我更换 T 具有 u32 ,那我就可以回去了 Some(self.count) ,但使用泛型是不可能的。

    这只是因为 u32 Copy 同时实施 Clone ,它的作用与副本的作用几乎相同,后者发生在非泛型上下文中。

    因此,此中的克隆操作是合理的,因为您希望返回计数器的值,同时仍拥有其自己的状态。当 T 该计数器是一个原始整数,例如 u32 ,克隆的价格和这个整数的拷贝一样便宜。

    除此之外,还可以为 T AddAssign<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())
        }
    }
    

    另请参见:

    推荐文章