私はRustを学ぼうとしています。私は多くの人のように、フィボナッチシーケンスのイテレーターを書くために出発します。私の最初のパスはu32
を使用して正常に動作したので、私はジェネリック版を書くことにしました。これは私の結果である: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のより高度なリファレンスコンセプトのいくつかを使用してこれを書くより良い方法があると思っていますが、これまでわかっていません。
1つのクイックフォローアップ:私はあなたが実装上のみ、構造体そのものに特性境界を設定していないことに気付きました。それは錆の大会ですか? –
@ MarkTozziそれは主に個人の好みに依存します。タイプを「誤って使用する」ことをより困難にしたい場合は、どこでも境界を繰り返すことができますが、例では過度のように見えます。 –
誰かが不思議に思っている場合:「どこで」構成されているか(HRTBs)と呼ばれています(https://doc.rust-lang.org/nomicon/hrtb)。 html – Sebastian