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