2016-12-05 9 views
5

私は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(), 
     } 
    } 
} 

私はu32num::BigUintでこれをテストし、それが正常に動作します。私はnext方法のすべてのクローニングについて心配しています。特に、追加の段階でなぜクローンする必要があるのか​​分かりません。

私はRustのより高度なリファレンスコンセプトのいくつかを使用してこれを書くより良い方法があると思っていますが、これまでわかっていません。

答えて

7

溶液がそうようwhere句を使用することである。

extern crate num; 

use num::One; 
use std::ops::Add; 

pub struct Fibonacci<T> { 
    nth: T, 
    n_plus_one_th: T, 
} 

impl<T> Fibonacci<T> 
    where T: One 
{ 
    pub fn new() -> Fibonacci<T> { 
     Fibonacci { 
      nth: T::one(), 
      n_plus_one_th: T::one(), 
     } 
    } 
} 

impl<T> Iterator for Fibonacci<T> 
    where for<'a> &'a T: Add<&'a T, Output = T> 
{ 
    type Item = T; 
    fn next(&mut self) -> Option<T> { 
     use std::mem::swap; 
     let mut temp = &self.nth + &self.n_plus_one_th; 
     swap(&mut self.nth, &mut temp); 
     swap(&mut self.n_plus_one_th, &mut self.nth); 
     Some(temp) 
    } 
} 

すなわち、for<'a> &'a T: Add<&'a T, Output=T>句「は、任意の寿命'a&'a T&'a TOutput=TのRHSとAddを実装しなければならないためとして読み出しすなわち、。 &Tを2つ追加して新しいTを取得することができます。

これで、残っている唯一の問題は値をシャッフルすることです。これはswap

私はまた、他の場所で制約を単純化する自由を取った(IntegerではなくOneのみ必要)。

+0

1つのクイックフォローアップ:私はあなたが実装上のみ、構造体そのものに特性境界を設定していないことに気付きました。それは錆の大会ですか? –

+0

@ MarkTozziそれは主に個人の好みに依存します。タイプを「誤って使用する」ことをより困難にしたい場合は、どこでも境界を繰り返すことができますが、例では過度のように見えます。 –

+0

誰かが不思議に思っている場合:「どこで」構成されているか(HRTBs)と呼ばれています(https://doc.rust-lang.org/nomicon/hrtb)。 html – Sebastian

関連する問題