5
我想学习Rust,和许多之前我一样,为实践写出了一个Fibonacci序列迭代器。我的第一个传球使用了u32
s,并且运行良好,所以我决定尝试编写一个通用版本。这是我的结果:如何避免在Rust中过度克隆?
use num::Integer;
use std::ops::Add;
pub struct Fibonacci<T: Integer + Add + Clone> {
nth: T,
n_plus_one_th: T,
}
impl<T: Integer + Add + Clone> Iterator for Fibonacci<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
let temp = self.nth.clone();
self.nth = self.n_plus_one_th.clone();
self.n_plus_one_th = temp.clone() + self.n_plus_one_th.clone();
Some(temp)
}
}
impl<T: Integer + Add + Clone> Fibonacci<T> {
pub fn new() -> Fibonacci<T> {
Fibonacci {
nth: T::one(),
n_plus_one_th: T::one(),
}
}
}
我有u32
和num::BigUint
进行了测试,它工作正常。不过,我很关心next
方法中的所有克隆。特别是,我不明白为什么我需要在添加步骤中进行克隆。
我怀疑有更好的方法来使用一些Rust的更高级的参考概念来编写它,但到目前为止我还没有弄明白。
快速跟进:我注意到你没有在结构本身上放置任何特征边界,只在实现上。那是一个Rust惯例吗? –
@MarkTozzi这主要取决于个人喜好。如果你想让一个类型的“误用”变得更加困难,那么你可以在任何地方重复这个界限,但是对于一个例子来说这似乎过分了。 –
如果有人也想知道:“哪里for”构建被称为高级特质界(Magic-of-Rank Trait Bounds,HRTBs),并在此处记录在https://doc.rust-lang.org/nomicon/hrtb。 HTML – Sebastian