如何在不使用克隆的情况下编写一个保持状态和 returns 值的通用迭代器?
How do I write a generic iterator that keeps a state and returns a value without using clone?
我试图编写一个通用迭代器,但我不知道如何在不使用 clone
的情况下 return 值。有没有办法在 next
函数和 return 引用中创建变量?如果我用 u32
替换 T
,那么我只能 return 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"),
}
}
一方面...不,您不能使迭代器 return 成为对计数器值的引用。 Iterator::next()
方法 return 是一个与接收者值 &mut self
没有生命周期联系的值,因此我们无法控制将在那里 return 编辑的引用的生命周期。这是必需的,因为我们无法修改该引用借用的值。这个问题在另一个 question.
中得到了更好的解释
另一方面,真正的问题出现在这里:
If I replace T
with u32
, then I can just return Some(self.count)
, but using generics, it is not possible.
这只是因为 u32
实现了 Copy
,这意味着它会在需要时被复制。实现了 Copy
的类型也实现了 Clone
,这将做与副本几乎相同的事情,这将发生在非泛型上下文中。
因此,您在此进行的克隆操作是合理的,因为您想要 return 计数器的值,同时仍然拥有它自己的状态。当该计数器的 T
是原始整数(例如 u32
时),克隆与该整数的副本一样便宜。
除此之外,您可以在 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())
}
}
另请参阅:
- Can I write an Iterator that mutates itself and then yields a reference into itself?
- Is there any way to return a reference to a variable created in a function?
我试图编写一个通用迭代器,但我不知道如何在不使用 clone
的情况下 return 值。有没有办法在 next
函数和 return 引用中创建变量?如果我用 u32
替换 T
,那么我只能 return 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"),
}
}
一方面...不,您不能使迭代器 return 成为对计数器值的引用。 Iterator::next()
方法 return 是一个与接收者值 &mut self
没有生命周期联系的值,因此我们无法控制将在那里 return 编辑的引用的生命周期。这是必需的,因为我们无法修改该引用借用的值。这个问题在另一个 question.
另一方面,真正的问题出现在这里:
If I replace
T
withu32
, then I can just returnSome(self.count)
, but using generics, it is not possible.
这只是因为 u32
实现了 Copy
,这意味着它会在需要时被复制。实现了 Copy
的类型也实现了 Clone
,这将做与副本几乎相同的事情,这将发生在非泛型上下文中。
因此,您在此进行的克隆操作是合理的,因为您想要 return 计数器的值,同时仍然拥有它自己的状态。当该计数器的 T
是原始整数(例如 u32
时),克隆与该整数的副本一样便宜。
除此之外,您可以在 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())
}
}
另请参阅:
- Can I write an Iterator that mutates itself and then yields a reference into itself?
- Is there any way to return a reference to a variable created in a function?